1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-08-26 01:33:56 +02:00
jami-client-qt/src/libclient/directrenderer.cpp
Andreas Traczyk 15e133301e avmodel: use synchronous callbacks for DecodingStarted/Stopped
This is an older issue that has resurfaced where mobile device rotation
at the beginning of a call cause a frame-copy to a stale buffer because
the DecodingStarted event is handled asynchronously.

Noticed on Windows but I believe any non-dbus build should have it.

So we make all the connections blocking and adjust some parameters.
This commit also removes the DecodingStarted handler in CallModel which
was causing the client's target video frame to be reallocated for each
account present.

Change-Id: I23ac4e0bd4b446e7a532f0d362f7ecd209d3c790
GitLab: #536
2022-09-29 11:45:09 -04:00

126 lines
3.2 KiB
C++

/*
* Copyright (C) 2012-2022 Savoir-faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "directrenderer.h"
#include "dbus/videomanager.h"
#include "videomanager_interface.h"
#include <QMutex>
namespace lrc {
namespace video {
using namespace lrc::api::video;
struct DirectRenderer::Impl : public QObject
{
Q_OBJECT
public:
Impl(DirectRenderer* parent)
: QObject(nullptr)
, parent_(parent)
{
configureTarget();
if (!VideoManager::instance().registerSinkTarget(parent_->id(), target))
qWarning() << "Cannot register " << parent_->id();
};
~Impl()
{
parent_->stopRendering();
VideoManager::instance().registerSinkTarget(parent_->id(), {});
}
// sink target callbacks
void configureTarget()
{
using namespace std::placeholders;
target.pull = std::bind(&Impl::pullCallback, this);
target.push = std::bind(&Impl::pushCallback, this, _1);
};
DRing::FrameBuffer pullCallback()
{
QMutexLocker lk(&mutex);
if (!frameBufferPtr) {
frameBufferPtr.reset(av_frame_alloc());
}
// A response to this signal should be used to provide client
// allocated buffer specs via the AVFrame structure.
// Important: Subscription to this signal MUST be synchronous(Qt::DirectConnection).
Q_EMIT parent_->frameBufferRequested(frameBufferPtr.get());
if (frameBufferPtr->data[0] == nullptr) {
return nullptr;
}
return std::move(frameBufferPtr);
};
void pushCallback(DRing::FrameBuffer buf)
{
{
QMutexLocker lk(&mutex);
frameBufferPtr = std::move(buf);
}
Q_EMIT parent_->frameUpdated();
};
private:
DirectRenderer* parent_;
public:
DRing::SinkTarget target;
QMutex mutex;
DRing::FrameBuffer frameBufferPtr;
};
DirectRenderer::DirectRenderer(const QString& id, const QSize& res)
: Renderer(id, res)
, pimpl_(std::make_unique<DirectRenderer::Impl>(this))
{}
DirectRenderer::~DirectRenderer() {}
void
DirectRenderer::startRendering()
{
Q_EMIT started(size());
}
void
DirectRenderer::stopRendering()
{
Q_EMIT stopped();
}
Frame
DirectRenderer::currentFrame() const
{
return {};
}
} // namespace video
} // namespace lrc
#include "moc_directrenderer.cpp"
#include "directrenderer.moc"