mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
Fix preview deadlock + preview on call connection + 1-1 call
This commit is contained in:
parent
2f6a4828cb
commit
41359252c9
5 changed files with 29 additions and 249 deletions
|
|
@ -99,6 +99,8 @@ QQuickFramebufferObject::Renderer *CameraGui::createRenderer(bool resetWindowId)
|
|||
lInfo() << "[Camera] (" << qmlName << ") " << (resetWindowId ? "Resetting" : "Setting")
|
||||
<< " Camera to ParticipantDeviceModel";
|
||||
if (resetWindowId) {
|
||||
renderer = (QQuickFramebufferObject::Renderer *)device->getNativeVideoWindowId();
|
||||
if (renderer) device->setNativeVideoWindowId(NULL);
|
||||
} else {
|
||||
renderer = (QQuickFramebufferObject::Renderer *)device->createNativeVideoWindowId();
|
||||
if (renderer) device->setNativeVideoWindowId(renderer);
|
||||
|
|
|
|||
|
|
@ -66,15 +66,19 @@ QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *ca
|
|||
} else {
|
||||
lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName();
|
||||
}
|
||||
App::postModelBlock(
|
||||
[&renderer, isFirst = (itCandidate == mCandidates.begin()), name = itCandidate->first->getQmlName()]() {
|
||||
renderer =
|
||||
(QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId();
|
||||
if (isFirst) {
|
||||
lDebug() << "[PreviewManager] " << name << " Set Native Preview Id";
|
||||
CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer);
|
||||
}
|
||||
});
|
||||
App::postModelBlock([&renderer, isFirst = (itCandidate == mCandidates.begin()),
|
||||
name = itCandidate->first->getQmlName()]() {
|
||||
renderer =
|
||||
(QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId();
|
||||
if (!renderer) { // TODO debug
|
||||
renderer =
|
||||
(QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId();
|
||||
}
|
||||
if (isFirst) {
|
||||
lDebug() << "[PreviewManager] " << name << " Set Native Preview Id";
|
||||
CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer);
|
||||
}
|
||||
});
|
||||
itCandidate->second = renderer;
|
||||
mCounterMutex.unlock();
|
||||
return renderer;
|
||||
|
|
@ -114,9 +118,9 @@ void PreviewManager::unsubscribe(QObject *sender) {
|
|||
}
|
||||
|
||||
void PreviewManager::activate() {
|
||||
App::postModelSync([]() { CoreModel::getInstance()->getCore()->enableVideoPreview(true); });
|
||||
App::postModelBlock([]() { CoreModel::getInstance()->getCore()->enableVideoPreview(true); });
|
||||
}
|
||||
|
||||
void PreviewManager::deactivate() {
|
||||
App::postModelSync([]() { CoreModel::getInstance()->getCore()->enableVideoPreview(false); });
|
||||
App::postModelBlock([]() { CoreModel::getInstance()->getCore()->enableVideoPreview(false); });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ Window {
|
|||
console.log("CALL", call)
|
||||
// if conference, the main item is only
|
||||
// displayed when state is connected
|
||||
if (!conferenceInfo)
|
||||
if (call && middleItemStackView.currentItem != inCallItem) middleItemStackView.replace(inCallItem)
|
||||
if (call && middleItemStackView.currentItem != inCallItem
|
||||
&& (!conferenceInfo || conference) )
|
||||
middleItemStackView.replace(inCallItem)
|
||||
}
|
||||
property var callObj
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Item {
|
|||
: null
|
||||
property string peerAddress:peerAddressObj ? peerAddressObj.value : ""
|
||||
property var identityAddress: account ? UtilsCpp.getDisplayName(account.core.identityAddress) : null
|
||||
property bool cameraEnabled: previewEnabled
|
||||
property bool cameraEnabled: previewEnabled || participantDevice && participantDevice.core.videoEnabled
|
||||
property string qmlName
|
||||
|
||||
Rectangle {
|
||||
|
|
@ -79,7 +79,8 @@ Item {
|
|||
Timer{
|
||||
id: resetTimer
|
||||
interval: 1
|
||||
onTriggered: {cameraLoader.reset=true; cameraLoader.reset=false;}
|
||||
triggeredOnStart: true
|
||||
onTriggered: {cameraLoader.reset = !cameraLoader.reset}
|
||||
}
|
||||
active: mainItem.visible && mainItem.cameraEnabled && !mainItem.reset
|
||||
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active)
|
||||
|
|
@ -100,12 +101,12 @@ Item {
|
|||
participantDevice: mainItem.participantDevice
|
||||
isPreview: mainItem.previewEnabled
|
||||
onRequestNewRenderer: {
|
||||
console.log("Request new renderer")
|
||||
console.log("Request new renderer for " +mainItem.qmlName)
|
||||
resetTimer.restart()
|
||||
}
|
||||
layer.enabled: true
|
||||
}
|
||||
|
||||
|
||||
ShaderEffect {
|
||||
id: roundEffect
|
||||
property variant src: cameraItem
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ Item{
|
|||
|
||||
Sticker {
|
||||
id: activeSpeakerSticker
|
||||
//call: mainItem.call
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
call: mainItem.call
|
||||
|
|
@ -47,6 +46,7 @@ Item{
|
|||
onTriggered: waitingTime.seconds += 1
|
||||
}
|
||||
ColumnLayout {
|
||||
id: waitingConnection
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30 * DefaultStyle.dp
|
||||
|
|
@ -90,15 +90,13 @@ Item{
|
|||
Sticker {
|
||||
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
|
||||
&& modelData.core.address != activeSpeakerSticker.address
|
||||
onVisibleChanged: console.log(modelData.core.address)
|
||||
height: visible ? 180 * DefaultStyle.dp : 0
|
||||
width: 300 * DefaultStyle.dp
|
||||
qmlName: 'M_'+index
|
||||
qmlName: 'S_'+index
|
||||
|
||||
participantDevice: modelData
|
||||
cameraEnabled: mainItem.call.core.cameraEnabled
|
||||
Component.onCompleted: console.log(modelData.core.address)
|
||||
previewEnabled: index == 0
|
||||
Component.onCompleted: console.log(qmlName + " is " +modelData.core.address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -106,7 +104,7 @@ Item{
|
|||
id: preview
|
||||
qmlName: 'P'
|
||||
previewEnabled: true
|
||||
visible: mainItem.call && allDevices.count <= 2
|
||||
visible: mainItem.call && allDevices.count <= 2 && !waitingConnection.visible
|
||||
onVisibleChanged: console.log(visible + " : " +allDevices.count)
|
||||
height: 180 * DefaultStyle.dp
|
||||
width: 300 * DefaultStyle.dp
|
||||
|
|
@ -143,230 +141,4 @@ Item{
|
|||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Sticker {
|
||||
id: preview
|
||||
visible: mainItem.callState != LinphoneEnums.CallState.End
|
||||
&& mainItem.callState != LinphoneEnums.CallState.Released
|
||||
height: 180 * DefaultStyle.dp
|
||||
width: 300 * DefaultStyle.dp
|
||||
anchors.right: mainItem.right
|
||||
anchors.bottom: mainItem.bottom
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||
anchors.bottomMargin: 10 * DefaultStyle.dp
|
||||
AccountProxy{
|
||||
id: accounts
|
||||
}
|
||||
account: accounts.defaultAccount
|
||||
previewEnabled: mainItem.call.core.cameraEnabled
|
||||
|
||||
MovableMouseArea {
|
||||
id: previewMouseArea
|
||||
anchors.fill: parent
|
||||
// visible: mainItem.participantCount <= 2
|
||||
movableArea: mainItem
|
||||
margin: 10 * DefaultStyle.dp
|
||||
function resetPosition(){
|
||||
preview.anchors.right = mainItem.right
|
||||
preview.anchors.bottom = mainItem.bottom
|
||||
preview.anchors.rightMargin = previewMouseArea.margin
|
||||
preview.anchors.bottomMargin = previewMouseArea.margin
|
||||
}
|
||||
onVisibleChanged: if(!visible){
|
||||
resetPosition()
|
||||
}
|
||||
drag.target: preview
|
||||
onDraggingChanged: if(dragging) {
|
||||
preview.anchors.right = undefined
|
||||
preview.anchors.bottom = undefined
|
||||
}
|
||||
onRequestResetPosition: resetPosition()
|
||||
}
|
||||
}
|
||||
|
||||
property int previousWidth
|
||||
Component.onCompleted: {
|
||||
previousWidth = width
|
||||
}
|
||||
onWidthChanged: {
|
||||
if (width < previousWidth) {
|
||||
previewMouseArea.updatePosition(0, 0)
|
||||
} else {
|
||||
previewMouseArea.updatePosition(width - previousWidth, 0)
|
||||
}
|
||||
previousWidth = width
|
||||
}*/
|
||||
|
||||
/*
|
||||
|
||||
Item {
|
||||
id: mainItem
|
||||
property CallModel callModel
|
||||
property bool isRightReducedLayout: false
|
||||
property bool isLeftReducedLayout: false
|
||||
property bool cameraEnabled: true
|
||||
property bool isConference: callModel && callModel.isConference
|
||||
property bool isConferenceReady: isConference && callModel.conferenceModel && callModel.conferenceModel.isReady
|
||||
|
||||
property int participantCount: isConference ? allDevices.count + 1 : 2 // +me. allDevices==0 if !conference
|
||||
|
||||
property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel {
|
||||
id: allDevices
|
||||
callModel: mainItem.callModel
|
||||
showMe: false
|
||||
|
||||
onConferenceCreated: cameraView.resetCamera()
|
||||
}
|
||||
|
||||
Sticker{
|
||||
id: cameraView
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: isRightReducedLayout || isLeftReducedLayout? 30 : 140
|
||||
anchors.rightMargin: isRightReducedLayout ? 10 : 140
|
||||
cameraQmlName: 'AS'
|
||||
callModel: mainItem.callModel
|
||||
currentDevice: isPreview
|
||||
? allDevices.me
|
||||
: mainItem.isConference
|
||||
? allDevices.activeSpeaker
|
||||
: null
|
||||
deactivateCamera: !mainItem.cameraEnabled || (isPreview && callModel.pausedByUser)
|
||||
? true
|
||||
: mainItem.isConference
|
||||
? (callModel && (callModel.pausedByUser || callModel.status === CallModel.CallStatusPaused) )
|
||||
|| (!(callModel && callModel.cameraEnabled) && mainItem.participantCount == 1)
|
||||
|| (currentDevice && !currentDevice.videoEnabled)// && mainItem.participantCount == 2)
|
||||
|| !mainItem.isConferenceReady
|
||||
: (callModel && (callModel.pausedByUser || callModel.status === CallModel.CallStatusPaused || !callModel.videoEnabled) )
|
||||
|| currentDevice && !currentDevice.videoEnabled
|
||||
isPreview: !preview.visible && mainItem.participantCount == 1
|
||||
onIsPreviewChanged: {cameraView.resetCamera() }
|
||||
isCameraFromDevice: isPreview
|
||||
isPaused: isPreview && callModel.pausedByUser
|
||||
? false
|
||||
: mainItem.isConference
|
||||
? //callModel && callModel.pausedByUser && mainItem.participantCount != 2 ||
|
||||
(currentDevice && currentDevice.isPaused)
|
||||
: callModel && !callModel.pausedByUser && (callModel.status === CallModel.CallStatusPaused)
|
||||
|
||||
quickTransition: true
|
||||
showCloseButton: false
|
||||
showActiveSpeakerOverlay: false // This is an active speaker. We don't need to show the indicator.
|
||||
showCustomButton: false
|
||||
avatarStickerBackgroundColor: isPreview ? IncallStyle.container.avatar.stickerPreviewBackgroundColor.color : IncallStyle.container.avatar.stickerBackgroundColor.color
|
||||
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
||||
}
|
||||
Item{// Need an item to not override Sticker internal states. States are needed for changing anchors.
|
||||
id: preview
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.rightMargin: 30
|
||||
anchors.bottomMargin: 15
|
||||
|
||||
height: visible ? miniViews.cellHeight : 0
|
||||
width: 16 * height / 9
|
||||
|
||||
visible: mainItem.isConferenceReady && allDevices.count >= 1
|
||||
|| (!mainItem.isConference && mainItem.callModel && mainItem.callModel.cameraEnabled)// use videoEnabled if we want to show the preview sticker
|
||||
|
||||
Loader{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 3
|
||||
sourceComponent:
|
||||
Sticker{
|
||||
id: previewSticker
|
||||
cameraQmlName: 'AS_Preview'
|
||||
deactivateCamera: !mainItem.cameraEnabled || !mainItem.callModel || callModel.pausedByUser || !mainItem.callModel.cameraEnabled
|
||||
currentDevice: allDevices.me
|
||||
isPreview: true
|
||||
callModel: mainItem.callModel
|
||||
isCameraFromDevice: true
|
||||
showCloseButton: false
|
||||
showCustomButton: false
|
||||
showAvatarBorder: true
|
||||
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerPreviewBackgroundColor.color
|
||||
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
||||
}
|
||||
active: parent.visible
|
||||
}
|
||||
|
||||
MovableMouseArea{
|
||||
id: dragger
|
||||
anchors.fill: parent
|
||||
visible: mainItem.participantCount <= 2
|
||||
function resetPosition(){
|
||||
preview.anchors.right = mainItem.right
|
||||
preview.anchors.bottom = mainItem.bottom
|
||||
}
|
||||
onVisibleChanged: if(!visible){
|
||||
resetPosition()
|
||||
}
|
||||
drag.target: preview
|
||||
onDraggingChanged: if(dragging){
|
||||
preview.anchors.right = undefined
|
||||
preview.anchors.bottom = undefined
|
||||
}
|
||||
onRequestResetPosition: resetPosition()
|
||||
}
|
||||
}
|
||||
|
||||
Item{
|
||||
id: miniViewArea
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: preview.top
|
||||
anchors.rightMargin: 30
|
||||
anchors.topMargin: 15
|
||||
anchors.bottomMargin: 0
|
||||
//---------------
|
||||
width: 16 * miniViews.cellHeight / 9
|
||||
visible: mainItem.isConferenceReady || !mainItem.isConference
|
||||
property int heightLeft: parent.height - preview.height
|
||||
onHeightLeftChanged: {Qt.callLater(miniViewArea.forceRefresh)}
|
||||
function forceRefresh(){// Force a content refresh via margins. Qt is buggy when managing sizes in ListView.
|
||||
++miniViewArea.anchors.topMargin
|
||||
--miniViewArea.anchors.topMargin
|
||||
}
|
||||
|
||||
ScrollableListView{
|
||||
id: miniViews
|
||||
property int cellHeight: 150
|
||||
anchors.fill: parent
|
||||
model : mainItem.isConference && mainItem.participantDevices.count > 1 ? mainItem.participantDevices : []
|
||||
spacing: 0
|
||||
verticalLayoutDirection: ListView.BottomToTop
|
||||
fitCacheToContent: false
|
||||
property int oldCount : 0// Count changed can be called without a change... (bug?). Use oldCount to avoid it.
|
||||
onCountChanged: {if(oldCount != count){ oldCount = count ; Qt.callLater(miniViewArea.forceRefresh)}}
|
||||
Component.onCompleted: {Qt.callLater(miniViewArea.forceRefresh)}
|
||||
delegate:Item{
|
||||
height: visible ? miniViews.cellHeight + 15 : 0
|
||||
width: visible ? miniViews.width : 0
|
||||
visible: cameraView.currentDevice != modelData
|
||||
clip:false
|
||||
Sticker{
|
||||
id: miniView
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 3
|
||||
anchors.leftMargin: 3
|
||||
anchors.rightMargin: 3
|
||||
anchors.bottomMargin: 18
|
||||
cameraQmlName: 'S_'+index
|
||||
deactivateCamera: (!mainItem.isConferenceReady || !mainItem.isConference)
|
||||
&& (index <0 || !mainItem.cameraEnabled || (!modelData.videoEnabled) || (callModel && callModel.pausedByUser) )
|
||||
currentDevice: modelData.isPreview ? null : modelData
|
||||
callModel: modelData.isPreview ? null : mainItem.callModel
|
||||
isCameraFromDevice: mainItem.isConference
|
||||
isPaused: currentDevice && currentDevice.isPaused
|
||||
showCloseButton: false
|
||||
showCustomButton: false
|
||||
showAvatarBorder: true
|
||||
avatarStickerBackgroundColor: IncallStyle.container.avatar.stickerBackgroundColor.color
|
||||
avatarBackgroundColor: IncallStyle.container.avatar.backgroundColor.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue