diff --git a/DeviceSource.cpp b/DeviceSource.cpp index 2a1dd98..68ad7f1 100644 --- a/DeviceSource.cpp +++ b/DeviceSource.cpp @@ -369,6 +369,11 @@ DeviceSource::DeviceSource(uint64_t id) : StreamSource(id), unplugged_(false) } DeviceSource::~DeviceSource() +{ + unsetDevice(); +} + +void DeviceSource::unsetDevice() { // unregister this device source from a Device handler auto h = std::find_if(Device::manager().handles_.begin(), Device::manager().handles_.end(), hasConnectedSource(this)); @@ -398,11 +403,18 @@ DeviceSource::~DeviceSource() void DeviceSource::setDevice(const std::string &devicename) { + if (device_.compare(devicename) == 0) + return; + // instanciate and wait for monitor initialization if not already initialized std::mutex mtx; std::unique_lock lck(mtx); Device::manager().monitor_initialization_.wait(lck, Device::initialized); + // if changing device + if (!device_.empty()) + unsetDevice(); + // remember device name device_ = devicename; @@ -449,11 +461,14 @@ void DeviceSource::setDevice(const std::string &devicename) pipeline << " ! videoconvert"; - // resize render buffer + // delete and reset render buffer to enforce re-init of StreamSource if (renderbuffer_) - renderbuffer_->resize(best.width, best.height); + delete renderbuffer_; + renderbuffer_ = nullptr; // new stream + if (stream_) + delete stream_; stream_ = h->stream = new Stream; // open gstreamer diff --git a/DeviceSource.h b/DeviceSource.h index 4d51027..59181e8 100644 --- a/DeviceSource.h +++ b/DeviceSource.h @@ -33,6 +33,7 @@ public: private: std::string device_; std::atomic unplugged_; + void unsetDevice(); }; struct DeviceConfig { diff --git a/Source.cpp b/Source.cpp index 5499941..315058d 100644 --- a/Source.cpp +++ b/Source.cpp @@ -492,45 +492,59 @@ void Source::attach(FrameBuffer *renderbuffer) delete renderbuffer_; renderbuffer_ = renderbuffer; - // create the surfaces to draw the frame buffer in the views - rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); - groups_[View::RENDERING]->attach(rendersurface_); - groups_[View::GEOMETRY]->attach(rendersurface_); + // only first time initialization + if ( mode_ == UNINITIALIZED ) { - // for mixing and layer views, add another surface to overlay - // (stippled view on top with transparency) - mixingsurface_ = new FrameBufferSurface(renderbuffer_, mixingshader_); - groups_[View::MIXING]->attach(mixingsurface_); - groups_[View::LAYER]->attach(mixingsurface_); + // create the surfaces to draw the frame buffer in the views + rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); + groups_[View::RENDERING]->attach(rendersurface_); + groups_[View::GEOMETRY]->attach(rendersurface_); - // for views showing a scaled mixing surface, a dedicated transparent surface allows grabbing - activesurface_ = new Surface(); - activesurface_->setTextureIndex(Resource::getTextureTransparent()); - groups_[View::TEXTURE]->attach(activesurface_); - groups_[View::MIXING]->attach(activesurface_); - groups_[View::LAYER]->attach(activesurface_); + // for mixing and layer views, add another surface to overlay + // (stippled view on top with transparency) + mixingsurface_ = new FrameBufferSurface(renderbuffer_, mixingshader_); + groups_[View::MIXING]->attach(mixingsurface_); + groups_[View::LAYER]->attach(mixingsurface_); - // Transition group node is optionnal - if (groups_[View::TRANSITION]->numChildren() > 0) - groups_[View::TRANSITION]->attach(mixingsurface_); + // for views showing a scaled mixing surface, a dedicated transparent surface allows grabbing + activesurface_ = new Surface(); + activesurface_->setTextureIndex(Resource::getTextureTransparent()); + groups_[View::TEXTURE]->attach(activesurface_); + groups_[View::MIXING]->attach(activesurface_); + groups_[View::LAYER]->attach(activesurface_); - // if a symbol is available, add it to overlay - if (symbol_) { - overlays_[View::MIXING]->attach( symbol_ ); - overlays_[View::LAYER]->attach( symbol_ ); - // hack to place the symbols in the corner independently of aspect ratio - symbol_->translation_.x += 0.1f * (renderbuffer_->aspectRatio()-1.f); + // Transition group node is optionnal + if (groups_[View::TRANSITION]->numChildren() > 0) + groups_[View::TRANSITION]->attach(mixingsurface_); + + // if a symbol is available, add it to overlay + if (symbol_) { + overlays_[View::MIXING]->attach( symbol_ ); + overlays_[View::LAYER]->attach( symbol_ ); + } + + // add lock icon to views (displayed on front) + groups_[View::LAYER]->attach( locker_ ); + groups_[View::MIXING]->attach( locker_ ); + groups_[View::GEOMETRY]->attach( locker_ ); + groups_[View::TEXTURE]->attach( locker_ ); + + // make the source visible + setMode(VISIBLE); + } + else { + rendersurface_->setFrameBuffer(renderbuffer_); + mixingsurface_->setFrameBuffer(renderbuffer_); } - // hack to place the initials in the corner independently of aspect ratio - initial_0_->translation_.x -= renderbuffer_->aspectRatio(); - initial_1_->translation_.x -= renderbuffer_->aspectRatio(); + // if a symbol is available + if (symbol_) + // hack to place the symbols in the corner independently of aspect ratio + symbol_->translation_.x = 1.1f * (renderbuffer_->aspectRatio()-1.f); - // add lock icon to views (displayed on front) - groups_[View::LAYER]->attach( locker_ ); - groups_[View::MIXING]->attach( locker_ ); - groups_[View::GEOMETRY]->attach( locker_ ); - groups_[View::TEXTURE]->attach( locker_ ); + // hack to place the initials in the corner independently of aspect ratio + initial_0_->translation_.x = 0.2f - renderbuffer_->aspectRatio(); + initial_1_->translation_.x = 0.4f - renderbuffer_->aspectRatio(); // scale all icon nodes to match aspect ratio for (int v = View::MIXING; v < View::INVALID; v++) { @@ -546,10 +560,6 @@ void Source::attach(FrameBuffer *renderbuffer) delete maskbuffer_; maskbuffer_ = new FrameBuffer( glm::vec3(0.5) * renderbuffer->resolution() ); - // make the source visible - if ( mode_ == UNINITIALIZED ) - setMode(VISIBLE); - // request update need_update_ = true; } diff --git a/StreamSource.cpp b/StreamSource.cpp index 23742c9..7f0c0d7 100644 --- a/StreamSource.cpp +++ b/StreamSource.cpp @@ -119,10 +119,10 @@ void StreamSource::init() // once the texture of media player is created if (stream_->texture() != Resource::getTextureBlack()) { - // get the texture index from media player, apply it to the media surface + // get the texture index from stream, apply it to the surface texturesurface_->setTextureIndex( stream_->texture() ); - // create Frame buffer matching size of media player + // create Frame buffer matching size of stream float height = float(stream_->width()) / stream_->aspectRatio(); FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, FrameBuffer::FrameBuffer_alpha); @@ -149,7 +149,7 @@ void StreamSource::setActive (bool on) // try to activate (may fail if source is cloned) Source::setActive(on); - if (stream_) { + if ( stream_ ) { // change status of stream (only if status changed) if (active_ != was_active) stream_->enable(active_); @@ -196,8 +196,7 @@ guint64 StreamSource::playtime () const { if ( stream_ ) return stream_->position(); - else - return 0; + return 0; } void StreamSource::update(float dt) @@ -205,6 +204,6 @@ void StreamSource::update(float dt) Source::update(dt); // update stream - if (stream_) + if ( stream_ ) stream_->update(); }