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")
|
lInfo() << "[Camera] (" << qmlName << ") " << (resetWindowId ? "Resetting" : "Setting")
|
||||||
<< " Camera to ParticipantDeviceModel";
|
<< " Camera to ParticipantDeviceModel";
|
||||||
if (resetWindowId) {
|
if (resetWindowId) {
|
||||||
|
renderer = (QQuickFramebufferObject::Renderer *)device->getNativeVideoWindowId();
|
||||||
|
if (renderer) device->setNativeVideoWindowId(NULL);
|
||||||
} else {
|
} else {
|
||||||
renderer = (QQuickFramebufferObject::Renderer *)device->createNativeVideoWindowId();
|
renderer = (QQuickFramebufferObject::Renderer *)device->createNativeVideoWindowId();
|
||||||
if (renderer) device->setNativeVideoWindowId(renderer);
|
if (renderer) device->setNativeVideoWindowId(renderer);
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,14 @@ QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *ca
|
||||||
} else {
|
} else {
|
||||||
lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName();
|
lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName();
|
||||||
}
|
}
|
||||||
App::postModelBlock(
|
App::postModelBlock([&renderer, isFirst = (itCandidate == mCandidates.begin()),
|
||||||
[&renderer, isFirst = (itCandidate == mCandidates.begin()), name = itCandidate->first->getQmlName()]() {
|
name = itCandidate->first->getQmlName()]() {
|
||||||
renderer =
|
renderer =
|
||||||
(QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId();
|
(QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId();
|
||||||
|
if (!renderer) { // TODO debug
|
||||||
|
renderer =
|
||||||
|
(QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId();
|
||||||
|
}
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
lDebug() << "[PreviewManager] " << name << " Set Native Preview Id";
|
lDebug() << "[PreviewManager] " << name << " Set Native Preview Id";
|
||||||
CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer);
|
CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer);
|
||||||
|
|
@ -114,9 +118,9 @@ void PreviewManager::unsubscribe(QObject *sender) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewManager::activate() {
|
void PreviewManager::activate() {
|
||||||
App::postModelSync([]() { CoreModel::getInstance()->getCore()->enableVideoPreview(true); });
|
App::postModelBlock([]() { CoreModel::getInstance()->getCore()->enableVideoPreview(true); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewManager::deactivate() {
|
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)
|
console.log("CALL", call)
|
||||||
// if conference, the main item is only
|
// if conference, the main item is only
|
||||||
// displayed when state is connected
|
// displayed when state is connected
|
||||||
if (!conferenceInfo)
|
if (call && middleItemStackView.currentItem != inCallItem
|
||||||
if (call && middleItemStackView.currentItem != inCallItem) middleItemStackView.replace(inCallItem)
|
&& (!conferenceInfo || conference) )
|
||||||
|
middleItemStackView.replace(inCallItem)
|
||||||
}
|
}
|
||||||
property var callObj
|
property var callObj
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ Item {
|
||||||
: null
|
: null
|
||||||
property string peerAddress:peerAddressObj ? peerAddressObj.value : ""
|
property string peerAddress:peerAddressObj ? peerAddressObj.value : ""
|
||||||
property var identityAddress: account ? UtilsCpp.getDisplayName(account.core.identityAddress) : null
|
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
|
property string qmlName
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -79,7 +79,8 @@ Item {
|
||||||
Timer{
|
Timer{
|
||||||
id: resetTimer
|
id: resetTimer
|
||||||
interval: 1
|
interval: 1
|
||||||
onTriggered: {cameraLoader.reset=true; cameraLoader.reset=false;}
|
triggeredOnStart: true
|
||||||
|
onTriggered: {cameraLoader.reset = !cameraLoader.reset}
|
||||||
}
|
}
|
||||||
active: mainItem.visible && mainItem.cameraEnabled && !mainItem.reset
|
active: mainItem.visible && mainItem.cameraEnabled && !mainItem.reset
|
||||||
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active)
|
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active)
|
||||||
|
|
@ -100,7 +101,7 @@ Item {
|
||||||
participantDevice: mainItem.participantDevice
|
participantDevice: mainItem.participantDevice
|
||||||
isPreview: mainItem.previewEnabled
|
isPreview: mainItem.previewEnabled
|
||||||
onRequestNewRenderer: {
|
onRequestNewRenderer: {
|
||||||
console.log("Request new renderer")
|
console.log("Request new renderer for " +mainItem.qmlName)
|
||||||
resetTimer.restart()
|
resetTimer.restart()
|
||||||
}
|
}
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ Item{
|
||||||
|
|
||||||
Sticker {
|
Sticker {
|
||||||
id: activeSpeakerSticker
|
id: activeSpeakerSticker
|
||||||
//call: mainItem.call
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
call: mainItem.call
|
call: mainItem.call
|
||||||
|
|
@ -47,6 +46,7 @@ Item{
|
||||||
onTriggered: waitingTime.seconds += 1
|
onTriggered: waitingTime.seconds += 1
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
id: waitingConnection
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 30 * DefaultStyle.dp
|
anchors.topMargin: 30 * DefaultStyle.dp
|
||||||
|
|
@ -90,15 +90,13 @@ Item{
|
||||||
Sticker {
|
Sticker {
|
||||||
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
|
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
|
||||||
&& modelData.core.address != activeSpeakerSticker.address
|
&& modelData.core.address != activeSpeakerSticker.address
|
||||||
onVisibleChanged: console.log(modelData.core.address)
|
|
||||||
height: visible ? 180 * DefaultStyle.dp : 0
|
height: visible ? 180 * DefaultStyle.dp : 0
|
||||||
width: 300 * DefaultStyle.dp
|
width: 300 * DefaultStyle.dp
|
||||||
qmlName: 'M_'+index
|
qmlName: 'S_'+index
|
||||||
|
|
||||||
participantDevice: modelData
|
participantDevice: modelData
|
||||||
cameraEnabled: mainItem.call.core.cameraEnabled
|
|
||||||
Component.onCompleted: console.log(modelData.core.address)
|
|
||||||
previewEnabled: index == 0
|
previewEnabled: index == 0
|
||||||
|
Component.onCompleted: console.log(qmlName + " is " +modelData.core.address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +104,7 @@ Item{
|
||||||
id: preview
|
id: preview
|
||||||
qmlName: 'P'
|
qmlName: 'P'
|
||||||
previewEnabled: true
|
previewEnabled: true
|
||||||
visible: mainItem.call && allDevices.count <= 2
|
visible: mainItem.call && allDevices.count <= 2 && !waitingConnection.visible
|
||||||
onVisibleChanged: console.log(visible + " : " +allDevices.count)
|
onVisibleChanged: console.log(visible + " : " +allDevices.count)
|
||||||
height: 180 * DefaultStyle.dp
|
height: 180 * DefaultStyle.dp
|
||||||
width: 300 * 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…
Reference in a new issue