diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt index 82a83dcb2..2eaeb68cc 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt @@ -959,7 +959,8 @@ class CallActivity : CallBaseActivity() { binding!!.composeParticipantGrid.setContent { MaterialTheme { ParticipantGrid( - participants = participantUiStates.toList() + participants = participantUiStates.toList(), + eglBase = rootEglBase!! ) { animateCallControls(true, 0) } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.kt index 64c1a0839..71c0fd428 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.kt @@ -148,7 +148,7 @@ class ParticipantDisplayItem( isStreamEnabled = isStreamEnabled, raisedHand = raisedHand?.state == true, avatarUrl = urlForAvatar, - surfaceViewRenderer = surfaceViewRenderer + mediaStream = mediaStream, ) } diff --git a/app/src/main/java/com/nextcloud/talk/call/ParticipantUiState.kt b/app/src/main/java/com/nextcloud/talk/call/ParticipantUiState.kt index 1804650d6..71b93e85f 100644 --- a/app/src/main/java/com/nextcloud/talk/call/ParticipantUiState.kt +++ b/app/src/main/java/com/nextcloud/talk/call/ParticipantUiState.kt @@ -7,7 +7,7 @@ package com.nextcloud.talk.call -import org.webrtc.SurfaceViewRenderer +import org.webrtc.MediaStream data class ParticipantUiState( val sessionKey: String, @@ -17,5 +17,5 @@ data class ParticipantUiState( val isStreamEnabled: Boolean, val raisedHand: Boolean, val avatarUrl: String?, - val surfaceViewRenderer: SurfaceViewRenderer? = null + val mediaStream: MediaStream? ) diff --git a/app/src/main/java/com/nextcloud/talk/call/components/ParticipantGrid.kt b/app/src/main/java/com/nextcloud/talk/call/components/ParticipantGrid.kt index 59d153c26..f3d750b50 100644 --- a/app/src/main/java/com/nextcloud/talk/call/components/ParticipantGrid.kt +++ b/app/src/main/java/com/nextcloud/talk/call/components/ParticipantGrid.kt @@ -27,9 +27,15 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.nextcloud.talk.call.ParticipantUiState +import org.webrtc.EglBase @Composable -fun ParticipantGrid(modifier: Modifier = Modifier, participants: List, onClick: () -> Unit) { +fun ParticipantGrid( + modifier: Modifier = Modifier, + eglBase: EglBase?, + participants: List, + onClick: () -> Unit +) { val configuration = LocalConfiguration.current val isPortrait = configuration.orientation == Configuration.ORIENTATION_PORTRAIT @@ -44,7 +50,8 @@ fun ParticipantGrid(modifier: Modifier = Modifier, participants: List { isStreamEnabled = true, raisedHand = true, avatarUrl = "", - surfaceViewRenderer = null + mediaStream = null ) participantList.add(participant) } diff --git a/app/src/main/java/com/nextcloud/talk/call/components/ParticipantTile.kt b/app/src/main/java/com/nextcloud/talk/call/components/ParticipantTile.kt index 448303b01..480ce530b 100644 --- a/app/src/main/java/com/nextcloud/talk/call/components/ParticipantTile.kt +++ b/app/src/main/java/com/nextcloud/talk/call/components/ParticipantTile.kt @@ -9,6 +9,7 @@ package com.nextcloud.talk.call.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -25,18 +26,25 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView import com.nextcloud.talk.R import com.nextcloud.talk.call.ParticipantUiState +import org.webrtc.EglBase +import org.webrtc.SurfaceViewRenderer @Composable -fun ParticipantTile(participant: ParticipantUiState, modifier: Modifier = Modifier) { +fun ParticipantTile( + participant: ParticipantUiState, + eglBase: EglBase?, + modifier: Modifier = Modifier +) { Box( modifier = modifier .clip(RoundedCornerShape(12.dp)) .background(Color.DarkGray) ) { - if (participant.isStreamEnabled && participant.surfaceViewRenderer != null) { - WebRTCVideoView(participant.surfaceViewRenderer) + if (participant.isStreamEnabled && participant.mediaStream != null) { + WebRTCVideoView(participant, eglBase) } else { AvatarWithFallback(participant) } @@ -94,11 +102,12 @@ fun ParticipantTilePreview() { isStreamEnabled = true, raisedHand = true, avatarUrl = "", - surfaceViewRenderer = null + mediaStream = null, ) ParticipantTile( participant = participant, modifier = Modifier - .fillMaxWidth() + .fillMaxWidth(), + eglBase = null ) } diff --git a/app/src/main/java/com/nextcloud/talk/call/components/WebRTCVideoView.kt b/app/src/main/java/com/nextcloud/talk/call/components/WebRTCVideoView.kt index d7bb69984..c3947a139 100644 --- a/app/src/main/java/com/nextcloud/talk/call/components/WebRTCVideoView.kt +++ b/app/src/main/java/com/nextcloud/talk/call/components/WebRTCVideoView.kt @@ -11,13 +11,28 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView +import com.nextcloud.talk.call.ParticipantUiState +import org.webrtc.EglBase import org.webrtc.SurfaceViewRenderer @Composable -fun WebRTCVideoView(surfaceViewRenderer: SurfaceViewRenderer) { +fun WebRTCVideoView( + participant: ParticipantUiState, + eglBase: EglBase?, +) { AndroidView( - factory = { surfaceViewRenderer }, - update = { /* No-op, renderer is already initialized and reused */ }, - modifier = Modifier.fillMaxSize() + factory = { context -> + SurfaceViewRenderer(context).apply { + init(eglBase?.eglBaseContext, null) + setEnableHardwareScaler(true) + setMirror(false) + participant.mediaStream?.videoTracks?.firstOrNull()?.addSink(this) + } + }, + modifier = Modifier.fillMaxSize(), + onRelease = { + participant.mediaStream?.videoTracks?.firstOrNull()?.removeSink(it) + it.release() + } ) }