Implementation of the limbo area in Mixing view, to change update mode

of source (active or not) and suspend mediaplayer (enabled or not).
This commit is contained in:
brunoherbelin
2020-06-21 00:52:59 +02:00
parent 10d0a8c04b
commit 8684d6f2c2
15 changed files with 1055 additions and 495 deletions

View File

@@ -37,6 +37,7 @@ void DrawVisitor::visit(Group &n)
// traverse children
glm::mat4 mv = modelview_;
for (NodeSet::iterator node = n.begin(); !done_ && node != n.end(); node++) {
if ( (*node)->visible_ )
(*node)->accept(*this);
modelview_ = mv;
}

View File

@@ -40,6 +40,7 @@ MediaPlayer::MediaPlayer(string name) : id_(name)
seekable_ = false;
isimage_ = false;
interlaced_ = false;
enabled_ = true;
need_loop_ = false;
v_frame_is_full_ = false;
rate_ = 1.0;
@@ -271,10 +272,37 @@ GstClockTime MediaPlayer::position()
return pos - start_position_;
}
void MediaPlayer::enable(bool on)
{
if ( enabled_ != on ) {
enabled_ = on;
GstState requested_state = GST_STATE_PAUSED;
if (enabled_) {
requested_state = desired_state_;
}
// apply state change
GstStateChangeReturn ret = gst_element_set_state (pipeline_, requested_state);
if (ret == GST_STATE_CHANGE_FAILURE) {
Log::Warning("MediaPlayer %s Failed to enable", gst_element_get_name(pipeline_));
failed_ = true;
}
}
}
bool MediaPlayer::isEnabled() const
{
return enabled_;
}
void MediaPlayer::play(bool on)
{
// cannot play an image
if (isimage_)
if (!enabled_ || isimage_)
return;
// request state
@@ -299,7 +327,7 @@ void MediaPlayer::play(bool on)
// all ready, apply state change immediately
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
if (ret == GST_STATE_CHANGE_FAILURE) {
Log::Warning("MediaPlayer %s Failed to start", gst_element_get_name(pipeline_));
Log::Warning("MediaPlayer %s Failed to play", gst_element_get_name(pipeline_));
failed_ = true;
}
#ifdef MEDIA_PLAYER_DEBUG
@@ -317,7 +345,7 @@ void MediaPlayer::play(bool on)
bool MediaPlayer::isPlaying(bool testpipeline) const
{
// image cannot play
if (isimage_)
if (!enabled_ || isimage_)
return false;
// if not ready yet, answer with requested state
@@ -328,8 +356,6 @@ bool MediaPlayer::isPlaying(bool testpipeline) const
GstState state;
gst_element_get_state (pipeline_, &state, NULL, GST_CLOCK_TIME_NONE);
return state == GST_STATE_PLAYING;
// return desired_state == GST_STATE_PLAYING;
}
@@ -345,7 +371,7 @@ void MediaPlayer::setLoop(MediaPlayer::LoopMode mode)
void MediaPlayer::rewind()
{
if (!seekable_)
if (!enabled_ || !seekable_)
return;
if (rate_ > 0.0)
@@ -360,7 +386,7 @@ void MediaPlayer::rewind()
void MediaPlayer::seekNextFrame()
{
// useful only when Paused
if (isPlaying())
if (!enabled_ || isPlaying())
return;
if ( loop_ != LOOP_NONE) {
@@ -376,7 +402,7 @@ void MediaPlayer::seekNextFrame()
void MediaPlayer::seekTo(GstClockTime pos)
{
if (!seekable_)
if (!enabled_ || !seekable_)
return;
// apply seek
@@ -387,7 +413,7 @@ void MediaPlayer::seekTo(GstClockTime pos)
void MediaPlayer::fastForward()
{
if (!seekable_)
if (!enabled_ || !seekable_)
return;
double step = SIGN(rate_) * 0.01 * static_cast<double>(duration_);
@@ -459,6 +485,9 @@ void MediaPlayer::update()
discoverer_ = nullptr;
}
if (!enabled_)
return;
// apply texture
if (v_frame_is_full_) {
// first occurence; create texture

View File

@@ -119,6 +119,11 @@ public:
* Must be called in update loop
* */
void update();
void enable(bool on);
bool isEnabled() const;
/**
* Pause / Play
* Can play backward if play speed is negative
@@ -256,6 +261,7 @@ private:
bool seekable_;
bool isimage_;
bool interlaced_;
bool enabled_;
void execute_open();
void execute_loop_command();

View File

@@ -11,7 +11,7 @@
#include "Visitor.h"
#include "Log.h"
MediaSource::MediaSource() : Source(), path_("")
MediaSource::MediaSource() : Source(), path_(""), media_playing_(true)
{
// create media player
mediaplayer_ = new MediaPlayer;
@@ -35,7 +35,7 @@ void MediaSource::setPath(const std::string &p)
{
path_ = p;
mediaplayer_->open(path_);
mediaplayer_->play(true);
mediaplayer_->play(media_playing_);
Log::Notify("Opening %s", p.c_str());
}
@@ -98,13 +98,30 @@ void MediaSource::init()
}
void MediaSource::setActive (bool on)
{
bool was_active = active_;
Source::setActive(on);
if ( active_ != was_active ) {
mediaplayer()->enable(active_);
}
}
void MediaSource::update(float dt)
{
// update video
mediaplayer_->update();
Source::update(dt);
}
void MediaSource::render()
{
if (!initialized_)
init();
else {
// update video
mediaplayer_->update();
// render the media player into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);

View File

@@ -10,6 +10,8 @@ public:
~MediaSource();
// implementation of source API
void update (float dt) override;
void setActive (bool on) override;
void render() override;
bool failed() const override;
uint texture() const override;
@@ -27,6 +29,7 @@ protected:
Surface *mediasurface_;
std::string path_;
MediaPlayer *mediaplayer_;
bool media_playing_;
};
#endif // MEDIASOURCE_H

View File

@@ -26,7 +26,7 @@ void Selection::remove(Source *s)
SourceList::iterator it = find(s);
if (it != selection_.end()) {
selection_.erase(it);
s->setMode(Source::NORMAL);
s->setMode(Source::VISIBLE);
}
}
@@ -83,7 +83,7 @@ void Selection::add(SourceList l)
void Selection::remove(SourceList l)
{
for(auto it = l.begin(); it != l.end(); it++)
(*it)->setMode(Source::NORMAL);
(*it)->setMode(Source::VISIBLE);
// generate new set as difference of current selection and give list
SourceList result;
@@ -95,7 +95,7 @@ void Selection::remove(SourceList l)
void Selection::clear()
{
for(auto it = selection_.begin(); it != selection_.end(); it++)
(*it)->setMode(Source::NORMAL);
(*it)->setMode(Source::VISIBLE);
selection_.clear();
}

View File

@@ -131,18 +131,25 @@ void SessionSource::init()
}
}
void SessionSource::update(float dt)
{
// delete a source which failed
if (session()->failedSource() != nullptr)
session()->deleteSource(session()->failedSource());
// update video
if (active_)
session_->update(dt);
Source::update(dt);
}
void SessionSource::render()
{
if (!initialized_)
init();
else {
// update session
session_->update(dt_);
// delete a source which failed
if (session()->failedSource() != nullptr)
session()->deleteSource(session()->failedSource());
// render the sesion into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin();

View File

@@ -11,6 +11,7 @@ public:
~SessionSource();
// implementation of source API
void update (float dt) override;
void render() override;
bool failed() const override;
uint texture() const override;

View File

@@ -15,12 +15,13 @@
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "Log.h"
#include "Mixer.h"
Source::Source() : initialized_(false), need_update_(true)
Source::Source() : initialized_(false), active_(true), need_update_(true)
{
sprintf(initials_, "__");
name_ = "Source";
mode_ = Source::HIDDEN;
mode_ = Source::UNINITIALIZED;
// create groups and overlays for each view
@@ -168,20 +169,23 @@ Source::Mode Source::mode() const
void Source::setMode(Source::Mode m)
{
mode_ = m;
bool visible = mode_ != Source::HIDDEN;
// make visible on first time
if ( mode_ == Source::UNINITIALIZED ) {
for (auto g = groups_.begin(); g != groups_.end(); g++)
(*g).second->visible_ = visible;
(*g).second->visible_ = true;
}
uint index_frame = mode_ == Source::NORMAL ? 0 : 1;
// choose frame if selected
uint index_frame = m == Source::SELECTED ? 1 : 0;
for (auto f = frames_.begin(); f != frames_.end(); f++)
(*f).second->setActive(index_frame);
bool current = mode_ == Source::CURRENT;
// show overlay if current
bool current = m == Source::CURRENT;
for (auto o = overlays_.begin(); o != overlays_.end(); o++)
(*o).second->visible_ = current;
mode_ = m;
}
// test update callback
@@ -228,8 +232,23 @@ void Source::attach(FrameBuffer *renderbuffer)
// groups_[View::GEOMETRY]->update_callbacks_.push_front(fix_ar);
// make the source visible
if ( mode_ == HIDDEN )
setMode(NORMAL);
if ( mode_ == UNINITIALIZED )
setMode(VISIBLE);
}
void Source::setActive (bool on)
{
active_ = on;
for(auto clone = clones_.begin(); clone != clones_.end(); clone++) {
if ( (*clone)->active() )
active_ = true;
}
groups_[View::RENDERING]->visible_ = active_;
groups_[View::GEOMETRY]->visible_ = active_;
groups_[View::LAYER]->visible_ = active_;
}
void Source::update(float dt)
@@ -246,6 +265,9 @@ void Source::update(float dt)
float alpha = 1.0 - CLAMP( ( dist.x * dist.x ) + ( dist.y * dist.y ), 0.f, 1.f );
blendingshader_->color.a = alpha;
// CHANGE update status based on limbo
setActive( glm::length(dist) < 1.3f );
// MODIFY geometry based on GEOMETRY node
groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_;
groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_;
@@ -359,6 +381,17 @@ void CloneSource::init()
}
}
void CloneSource::setActive (bool on)
{
active_ = on;
groups_[View::RENDERING]->visible_ = active_;
groups_[View::GEOMETRY]->visible_ = active_;
groups_[View::LAYER]->visible_ = active_;
origin_->touch();
}
void CloneSource::render()
{
if (!initialized_)

View File

@@ -38,42 +38,47 @@ public:
// manipulate name of source
void setName (const std::string &name);
inline std::string name () const { return name_; }
inline const char *initials() const { return initials_; }
inline const char *initials () const { return initials_; }
// cloning mechanism
virtual CloneSource *clone();
virtual CloneSource *clone ();
// Display mode
typedef enum {
HIDDEN = 0,
NORMAL = 1,
UNINITIALIZED = 0,
VISIBLE = 1,
SELECTED = 2,
CURRENT = 3
} Mode;
Mode mode() const;
void setMode(Mode m);
Mode mode () const;
void setMode (Mode m);
// get handle on the nodes used to manipulate the source in a view
inline Group *group(View::Mode m) const { return groups_.at(m); }
inline Node *groupNode(View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
inline Group *group (View::Mode m) const { return groups_.at(m); }
inline Node *groupNode (View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
// tests if a given node is part of the source
bool contains(Node *node) const;
bool contains (Node *node) const;
// a Source has a shader to control image processing effects
inline ImageProcessingShader *processingShader() const { return rendershader_; }
inline ImageProcessingShader *processingShader () const { return rendershader_; }
// a Source has a shader to control mixing effects
inline ImageShader *blendingShader() const { return blendingshader_; }
inline ImageShader *blendingShader () const { return blendingshader_; }
// every Source has a frame buffer from the renderbuffer
virtual FrameBuffer *frame() const;
virtual FrameBuffer *frame () const;
// touch to request update
inline void touch() { need_update_ = true; }
inline void touch () { need_update_ = true; }
// a Source shall be updated before displayed (Mixing, Geometry and Layer)
void update (float dt);
virtual void update (float dt);
// update mode
virtual void setActive (bool on);
inline bool active () { return active_; }
// accept all kind of visitors
virtual void accept (Visitor& v);
@@ -143,6 +148,7 @@ protected:
Handles *handle_[4];
// update
bool active_;
bool need_update_;
float dt_;
Group *stored_status_;
@@ -161,6 +167,7 @@ public:
~CloneSource();
// implementation of source API
void setActive (bool on) override;
void render() override;
uint texture() const override { return origin_->texture(); }
bool failed() const override { return origin_ == nullptr; }

View File

@@ -795,7 +795,7 @@ void UserInterface::RenderMediaPlayer()
}
ImGui::SetCursorScreenPos(draw_pos);
if (mp->duration() != GST_CLOCK_TIME_NONE) {
if ( mp->isEnabled() && mp->duration() != GST_CLOCK_TIME_NONE) {
if (ImGui::Button(ICON_FA_FAST_BACKWARD))
mp->rewind();

View File

@@ -145,7 +145,7 @@ void View::select(glm::vec2 A, glm::vec2 B)
}
MixingView::MixingView() : View(MIXING)
MixingView::MixingView() : View(MIXING), limbo_scale_(1.3f)
{
// read default settings
if ( Settings::application.views[mode_].name.empty() ) {
@@ -162,7 +162,12 @@ MixingView::MixingView() : View(MIXING)
scene.bg()->attach(disk);
Mesh *circle = new Mesh("mesh/circle.ply");
circle->shader()->color = glm::vec4( COLOR_FRAME, 1.f );
circle->shader()->color = glm::vec4( COLOR_FRAME, 0.9f );
scene.bg()->attach(circle);
circle = new Mesh("mesh/circle.ply");
circle->scale_ = glm::vec3(limbo_scale_, limbo_scale_, 1.f);
circle->shader()->color = glm::vec4( COLOR_LIMBO_CIRCLE, 0.6f );
scene.bg()->attach(circle);
}

2
View.h
View File

@@ -89,9 +89,11 @@ public:
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>) override;
void setAlpha (Source *s);
inline float limboScale() { return limbo_scale_; }
private:
uint textureMixingQuadratic();
float limbo_scale_;
};
class RenderView : public View

View File

@@ -57,6 +57,7 @@
#define COLOR_DEFAULT_SOURCE 0.8f, 0.8f, 0.8f
#define COLOR_HIGHLIGHT_SOURCE 1.f, 1.f, 1.f
#define COLOR_FRAME 0.8f, 0.f, 0.8f
#define COLOR_LIMBO_CIRCLE 0.7f, 0.7f, 0.7f
// from glmixer
#define TEXTURE_REQUIRED_MAXIMUM 2048
@@ -84,7 +85,7 @@
#define COLOR_CIRCLE_MOVE 230, 30, 230
#define COLOR_DRAWINGS 180, 180, 180
#define COLOR_LIMBO 35, 35, 35
#define COLOR_LIMBO_CIRCLE 210, 160, 210
//#define COLOR_LIMBO_CIRCLE 210, 160, 210
#define COLOR_FADING 25, 25, 25
#define COLOR_FLASHING 250, 250, 250
#define COLOR_FRAME_MOVE 230, 30, 230

File diff suppressed because it is too large Load Diff