BugFix: change Device of DeviceSource with different resolution

This commit is contained in:
Bruno Herbelin
2022-05-22 22:04:45 +02:00
parent 4600253d1e
commit 8d95bd16fd
4 changed files with 69 additions and 44 deletions

View File

@@ -369,6 +369,11 @@ DeviceSource::DeviceSource(uint64_t id) : StreamSource(id), unplugged_(false)
} }
DeviceSource::~DeviceSource() DeviceSource::~DeviceSource()
{
unsetDevice();
}
void DeviceSource::unsetDevice()
{ {
// unregister this device source from a Device handler // unregister this device source from a Device handler
auto h = std::find_if(Device::manager().handles_.begin(), Device::manager().handles_.end(), hasConnectedSource(this)); 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) void DeviceSource::setDevice(const std::string &devicename)
{ {
if (device_.compare(devicename) == 0)
return;
// instanciate and wait for monitor initialization if not already initialized // instanciate and wait for monitor initialization if not already initialized
std::mutex mtx; std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx); std::unique_lock<std::mutex> lck(mtx);
Device::manager().monitor_initialization_.wait(lck, Device::initialized); Device::manager().monitor_initialization_.wait(lck, Device::initialized);
// if changing device
if (!device_.empty())
unsetDevice();
// remember device name // remember device name
device_ = devicename; device_ = devicename;
@@ -449,11 +461,14 @@ void DeviceSource::setDevice(const std::string &devicename)
pipeline << " ! videoconvert"; pipeline << " ! videoconvert";
// resize render buffer // delete and reset render buffer to enforce re-init of StreamSource
if (renderbuffer_) if (renderbuffer_)
renderbuffer_->resize(best.width, best.height); delete renderbuffer_;
renderbuffer_ = nullptr;
// new stream // new stream
if (stream_)
delete stream_;
stream_ = h->stream = new Stream; stream_ = h->stream = new Stream;
// open gstreamer // open gstreamer

View File

@@ -33,6 +33,7 @@ public:
private: private:
std::string device_; std::string device_;
std::atomic<bool> unplugged_; std::atomic<bool> unplugged_;
void unsetDevice();
}; };
struct DeviceConfig { struct DeviceConfig {

View File

@@ -492,6 +492,9 @@ void Source::attach(FrameBuffer *renderbuffer)
delete renderbuffer_; delete renderbuffer_;
renderbuffer_ = renderbuffer; renderbuffer_ = renderbuffer;
// only first time initialization
if ( mode_ == UNINITIALIZED ) {
// create the surfaces to draw the frame buffer in the views // create the surfaces to draw the frame buffer in the views
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_);
groups_[View::RENDERING]->attach(rendersurface_); groups_[View::RENDERING]->attach(rendersurface_);
@@ -518,20 +521,31 @@ void Source::attach(FrameBuffer *renderbuffer)
if (symbol_) { if (symbol_) {
overlays_[View::MIXING]->attach( symbol_ ); overlays_[View::MIXING]->attach( symbol_ );
overlays_[View::LAYER]->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);
} }
// hack to place the initials in the corner independently of aspect ratio
initial_0_->translation_.x -= renderbuffer_->aspectRatio();
initial_1_->translation_.x -= renderbuffer_->aspectRatio();
// add lock icon to views (displayed on front) // add lock icon to views (displayed on front)
groups_[View::LAYER]->attach( locker_ ); groups_[View::LAYER]->attach( locker_ );
groups_[View::MIXING]->attach( locker_ ); groups_[View::MIXING]->attach( locker_ );
groups_[View::GEOMETRY]->attach( locker_ ); groups_[View::GEOMETRY]->attach( locker_ );
groups_[View::TEXTURE]->attach( locker_ ); groups_[View::TEXTURE]->attach( locker_ );
// make the source visible
setMode(VISIBLE);
}
else {
rendersurface_->setFrameBuffer(renderbuffer_);
mixingsurface_->setFrameBuffer(renderbuffer_);
}
// 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);
// 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 // scale all icon nodes to match aspect ratio
for (int v = View::MIXING; v < View::INVALID; v++) { for (int v = View::MIXING; v < View::INVALID; v++) {
NodeSet::iterator node; NodeSet::iterator node;
@@ -546,10 +560,6 @@ void Source::attach(FrameBuffer *renderbuffer)
delete maskbuffer_; delete maskbuffer_;
maskbuffer_ = new FrameBuffer( glm::vec3(0.5) * renderbuffer->resolution() ); maskbuffer_ = new FrameBuffer( glm::vec3(0.5) * renderbuffer->resolution() );
// make the source visible
if ( mode_ == UNINITIALIZED )
setMode(VISIBLE);
// request update // request update
need_update_ = true; need_update_ = true;
} }

View File

@@ -119,10 +119,10 @@ void StreamSource::init()
// once the texture of media player is created // once the texture of media player is created
if (stream_->texture() != Resource::getTextureBlack()) { 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() ); 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(); float height = float(stream_->width()) / stream_->aspectRatio();
FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, FrameBuffer::FrameBuffer_alpha); 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) // try to activate (may fail if source is cloned)
Source::setActive(on); Source::setActive(on);
if (stream_) { if ( stream_ ) {
// change status of stream (only if status changed) // change status of stream (only if status changed)
if (active_ != was_active) if (active_ != was_active)
stream_->enable(active_); stream_->enable(active_);
@@ -196,7 +196,6 @@ guint64 StreamSource::playtime () const
{ {
if ( stream_ ) if ( stream_ )
return stream_->position(); return stream_->position();
else
return 0; return 0;
} }
@@ -205,6 +204,6 @@ void StreamSource::update(float dt)
Source::update(dt); Source::update(dt);
// update stream // update stream
if (stream_) if ( stream_ )
stream_->update(); stream_->update();
} }