Fixed black thumbnails when joining conference without bundle mode

This commit is contained in:
Sylvain Berfini 2025-05-12 16:10:56 +02:00
parent 3697c5e3c4
commit 5618ce2e88
5 changed files with 31 additions and 44 deletions

View file

@ -24,7 +24,6 @@ import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.MediaDirection
import org.linphone.core.ParticipantDevice
import org.linphone.core.ParticipantDeviceListenerStub
import org.linphone.core.StreamType
@ -57,7 +56,7 @@ class ConferenceParticipantDeviceModel
val isVideoAvailable = MutableLiveData<Boolean>()
val isSendingVideo = MutableLiveData<Boolean>()
val isThumbnailAvailable = MutableLiveData<Boolean>()
val isJoining = MutableLiveData<Boolean>()
@ -108,28 +107,6 @@ class ConferenceParticipantDeviceModel
isSpeaking.postValue(speaking)
}
@WorkerThread
override fun onStreamAvailabilityChanged(
participantDevice: ParticipantDevice,
available: Boolean,
streamType: StreamType?
) {
Log.d(
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] stream [$streamType] availability changed to ${if (available) "available" else "not available"}"
)
}
@WorkerThread
override fun onStreamCapabilityChanged(
participantDevice: ParticipantDevice,
direction: MediaDirection?,
streamType: StreamType?
) {
Log.d(
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] stream [$streamType] capability changed to [$direction]"
)
}
@WorkerThread
override fun onScreenSharingChanged(
participantDevice: ParticipantDevice,
@ -149,19 +126,21 @@ class ConferenceParticipantDeviceModel
Log.i(
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] thumbnail availability changed to ${if (available) "available" else "not available"}"
)
isVideoAvailable.postValue(available)
isThumbnailAvailable.postValue(available)
}
@WorkerThread
override fun onThumbnailStreamCapabilityChanged(
override fun onStreamAvailabilityChanged(
participantDevice: ParticipantDevice,
direction: MediaDirection?
available: Boolean,
streamType: StreamType?
) {
Log.i(
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] thumbnail capability changed to [$direction]"
)
val sending = direction == MediaDirection.SendRecv || direction == MediaDirection.SendOnly
isSendingVideo.postValue(sending)
if (streamType == StreamType.Video) {
Log.i(
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] video stream availability changed to ${if (available) "available" else "not available"}"
)
isVideoAvailable.postValue(available)
}
}
}
@ -196,10 +175,18 @@ class ConferenceParticipantDeviceModel
Log.i("$TAG Participant [${device.address.asStringUriOnly()}] is sharing its screen")
}
isVideoAvailable.postValue(device.getStreamAvailability(StreamType.Video))
val videoCapability = device.getStreamCapability(StreamType.Video)
isSendingVideo.postValue(
videoCapability == MediaDirection.SendRecv || videoCapability == MediaDirection.SendOnly
val videoAvailability = device.getStreamAvailability(StreamType.Video)
isVideoAvailable.postValue(videoAvailability)
Log.i(
"$TAG Participant device [${device.address.asStringUriOnly()}] video stream availability is ${if (videoAvailability) "available" else "not available"}"
)
// In case of joining conference without bundle mode, thumbnail stream availability will be false,
// but we need to display our video preview for video stream to be sent
val thumbnailVideoAvailability = if (isMe) videoAvailability else device.thumbnailStreamAvailability
isThumbnailAvailable.postValue(thumbnailVideoAvailability)
Log.i(
"$TAG Participant device [${device.address.asStringUriOnly()}] thumbnail availability is ${if (thumbnailVideoAvailability) "available" else "not available"}"
)
}

View file

@ -27,7 +27,7 @@
layout="@layout/contact_avatar_huge"
android:layout_marginTop="5dp"
bind:model="@{conferenceViewModel.activeSpeaker.avatarModel}"
android:visibility="@{conferenceViewModel.activeSpeaker.isSendingVideo || conferenceViewModel.activeSpeaker.isJoining || !conferenceViewModel.activeSpeaker.isInConference ? View.GONE : View.VISIBLE}"
android:visibility="@{conferenceViewModel.activeSpeaker.isVideoAvailable || conferenceViewModel.activeSpeaker.isJoining || !conferenceViewModel.activeSpeaker.isInConference ? View.GONE : View.VISIBLE}"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintWidth_max="@dimen/avatar_in_call_size"
app:layout_constraintHeight_max="@dimen/avatar_in_call_size"
@ -42,7 +42,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:visibility="@{conferenceViewModel.activeSpeaker.isSendingVideo &amp;&amp; conferenceViewModel.activeSpeaker.isInConference ? View.VISIBLE : View.GONE, default=gone}"
android:visibility="@{conferenceViewModel.activeSpeaker.isVideoAvailable &amp;&amp; conferenceViewModel.activeSpeaker.isInConference ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"

View file

@ -27,7 +27,7 @@
android:id="@+id/avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{model.isSendingVideo || model.isJoining || !model.isInConference ? View.GONE : View.VISIBLE}"
android:visibility="@{model.isThumbnailAvailable || model.isJoining || !model.isInConference ? View.GONE : View.VISIBLE}"
layout="@layout/contact_avatar_medium"
bind:model="@{model.avatarModel}"
bind:hidePresence="@{true}"
@ -43,7 +43,7 @@
app:alignTopRight="false"
app:displayMode="hybrid"
participantTextureView="@{model}"
android:visibility="@{model.isSendingVideo &amp;&amp; model.isInConference ? View.VISIBLE : View.GONE, default=gone}"
android:visibility="@{model.isThumbnailAvailable &amp;&amp; model.isInConference ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View file

@ -27,7 +27,7 @@
layout="@layout/contact_avatar_huge"
android:layout_marginTop="5dp"
bind:model="@{conferenceViewModel.activeSpeaker.avatarModel}"
android:visibility="@{conferenceViewModel.activeSpeaker.isSendingVideo || conferenceViewModel.activeSpeaker.isJoining || !conferenceViewModel.activeSpeaker.isInConference ? View.GONE : View.VISIBLE}"
android:visibility="@{conferenceViewModel.activeSpeaker.isVideoAvailable || conferenceViewModel.activeSpeaker.isJoining || !conferenceViewModel.activeSpeaker.isInConference ? View.GONE : View.VISIBLE}"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintWidth_max="@dimen/avatar_in_call_size"
app:layout_constraintHeight_max="@dimen/avatar_in_call_size"
@ -41,7 +41,7 @@
android:id="@+id/active_speaker_surface"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="@{conferenceViewModel.activeSpeaker.isSendingVideo &amp;&amp; conferenceViewModel.activeSpeaker.isInConference ? View.VISIBLE : View.GONE, default=gone}"
android:visibility="@{conferenceViewModel.activeSpeaker.isVideoAvailable &amp;&amp; conferenceViewModel.activeSpeaker.isInConference ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/active_speaker_miniatures_horizontal_layout"
app:layout_constraintStart_toStartOf="parent"

View file

@ -27,7 +27,7 @@
android:id="@+id/avatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{model.isSendingVideo || model.isJoining || !model.isInConference ? View.GONE : View.VISIBLE}"
android:visibility="@{model.isThumbnailAvailable || model.isJoining || !model.isInConference ? View.GONE : View.VISIBLE}"
layout="@layout/contact_avatar_big"
bind:model="@{model.avatarModel}"
bind:hidePresence="@{true}"
@ -43,7 +43,7 @@
app:alignTopRight="false"
app:displayMode="hybrid"
participantTextureView="@{model}"
android:visibility="@{model.isSendingVideo &amp;&amp; model.isInConference ? View.VISIBLE : View.GONE, default=gone}"
android:visibility="@{model.isThumbnailAvailable &amp;&amp; model.isInConference ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"