Commit 9f1fc6df authored by Ronan Abhamon's avatar Ronan Abhamon

fix(src/components/camera/Camera): deal with multi-threads

parent b1f294f5
......@@ -27,6 +27,7 @@
#include "Camera.hpp"
#include <QFileInfo>
#include <QThread>
#include <QQuickWindow>
// =============================================================================
......@@ -48,6 +49,9 @@ struct CameraStateBinder {
f->glDisable(GL_CULL_FACE);
f->glDisable(GL_DEPTH_TEST);
// Process at next tick.
m_renderer->update();
}
CameraRenderer *m_renderer;
......@@ -78,21 +82,27 @@ QOpenGLFramebufferObject *CameraRenderer::createFramebufferObject (const QSize &
format.setInternalTextureFormat(GL_RGBA8);
format.setSamples(4);
CoreManager *core = CoreManager::getInstance();
core->lockVideoRender();
m_context_info->width = size.width();
m_context_info->height = size.height();
m_context_info->functions = MSFunctions::getInstance()->getFunctions();
m_need_sync = true;
updateWindowId();
core->unlockVideoRender();
return new QOpenGLFramebufferObject(size, format);
}
void CameraRenderer::render () {
CameraStateBinder state(this);
if (!m_linphone_call)
return;
CameraStateBinder state(this);
// Draw with ms filter.
{
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
......@@ -115,38 +125,27 @@ void CameraRenderer::render () {
// Synchronize opengl calls with QML.
if (m_window)
m_window->resetOpenGLState();
// Process at next tick.
update();
}
void CameraRenderer::synchronize (QQuickFramebufferObject *item) {
m_window = item->window();
if (!m_need_sync) {
Camera *camera = qobject_cast<Camera *>(item);
shared_ptr<linphone::Call> linphone_call = camera->getCall()->getLinphoneCall();
bool is_preview = camera->m_is_preview;
m_linphone_call = camera->getCall()->getLinphoneCall();
m_is_preview = camera->m_is_preview;
if (m_linphone_call == linphone_call && m_is_preview == is_preview)
return;
m_linphone_call = linphone_call;
m_is_preview = is_preview;
}
m_need_sync = false;
updateWindowId();
}
qInfo() << QStringLiteral("Set context info (width: %1, height: %2, is_preview: %3).")
void CameraRenderer::updateWindowId () {
qInfo() << "Thread" << QThread::currentThread() << QStringLiteral("Set context info (width: %1, height: %2, is_preview: %3).")
.arg(m_context_info->width).arg(m_context_info->height).arg(m_is_preview);
void *window_id = const_cast<ContextInfo *>(m_context_info);
if (m_is_preview)
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(window_id);
else
m_linphone_call->setNativeVideoWindowId(window_id);
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(m_context_info);
else if (m_linphone_call)
m_linphone_call->setNativeVideoWindowId(m_context_info);
}
// -----------------------------------------------------------------------------
......@@ -159,25 +158,10 @@ Camera::Camera (QQuickItem *parent) : QQuickFramebufferObject(parent) {
setMirrorVertically(true);
}
Camera::~Camera () {
CoreManager *core = CoreManager::getInstance();
core->lockVideoRender();
if (m_is_preview)
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(nullptr);
else
m_call->getLinphoneCall()->setNativeVideoWindowId(nullptr);
core->unlockVideoRender();
}
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
return new CameraRenderer();
}
// -----------------------------------------------------------------------------
void Camera::mousePressEvent (QMouseEvent *) {
setFocus(true);
}
......@@ -191,7 +175,21 @@ CallModel *Camera::getCall () const {
void Camera::setCall (CallModel *call) {
if (m_call != call) {
m_call = call;
update();
emit callChanged(m_call);
}
}
bool Camera::getIsPreview () const {
return m_is_preview;
}
void Camera::setIsPreview (bool status) {
if (m_is_preview != status) {
m_is_preview = status;
update();
emit isPreviewChanged(status);
}
}
......@@ -35,6 +35,7 @@ struct ContextInfo;
class CameraRenderer : public QQuickFramebufferObject::Renderer {
friend class Camera;
friend struct CameraStateBinder;
public:
CameraRenderer ();
......@@ -46,8 +47,9 @@ protected:
void synchronize (QQuickFramebufferObject *item) override;
private:
void updateWindowId ();
ContextInfo *m_context_info;
bool m_need_sync = false;
bool m_is_preview = false;
shared_ptr<linphone::Call> m_linphone_call;
......@@ -63,11 +65,11 @@ class Camera : public QQuickFramebufferObject {
Q_OBJECT;
Q_PROPERTY(CallModel * call READ getCall WRITE setCall NOTIFY callChanged);
Q_PROPERTY(bool isPreview MEMBER m_is_preview NOTIFY isPreviewChanged);
Q_PROPERTY(bool isPreview READ getIsPreview WRITE setIsPreview NOTIFY isPreviewChanged);
public:
Camera (QQuickItem *parent = Q_NULLPTR);
~Camera ();
~Camera () = default;
QQuickFramebufferObject::Renderer *createRenderer () const override;
......@@ -82,6 +84,9 @@ private:
CallModel *getCall () const;
void setCall (CallModel *call);
bool getIsPreview () const;
void setIsPreview (bool status);
bool m_is_preview = false;
CallModel *m_call = nullptr;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment