Skip to content

Commit 54e226e

Browse files
Merge branch 'develop'
2 parents 7676d9a + 91da106 commit 54e226e

File tree

6 files changed

+219
-75
lines changed

6 files changed

+219
-75
lines changed

buildSrc/src/main/kotlin/io/getstream/video/android/Configuration.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ object Configuration {
66
const val minSdk = 24
77
const val majorVersion = 1
88
const val minorVersion = 4
9-
const val patchVersion = 2
9+
const val patchVersion = 3
1010
const val versionName = "$majorVersion.$minorVersion.$patchVersion"
11-
const val versionCode = 49
11+
const val versionCode = 50
1212
const val snapshotVersionName = "$majorVersion.$minorVersion.${patchVersion + 1}-SNAPSHOT"
1313
const val artifactGroup = "io.getstream"
14-
const val streamVideoCallGooglePlayVersion = "1.4.2"
14+
const val streamVideoCallGooglePlayVersion = "1.4.3"
1515
const val streamWebRtcVersionName = "1.3.6"
1616
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/MediaManager.kt

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import android.os.Build
2929
import android.os.IBinder
3030
import androidx.core.content.ContextCompat
3131
import androidx.core.content.getSystemService
32-
import io.getstream.android.video.generated.models.OwnCapability
3332
import io.getstream.android.video.generated.models.VideoSettingsResponse
3433
import io.getstream.log.taggedLogger
3534
import io.getstream.video.android.core.audio.AudioHandler
@@ -367,17 +366,11 @@ class MicrophoneManager(
367366
// API
368367
/** Enable the audio, the rtc engine will automatically inform the SFU */
369368
internal fun enable(fromUser: Boolean = true) {
370-
val canUserSendAudio = with(mediaManager.call.state) {
371-
ownCapabilities.value.contains(OwnCapability.SendAudio)
372-
}
373-
374-
if (canUserSendAudio) {
375-
enforceSetup {
376-
if (fromUser) {
377-
_status.value = DeviceStatus.Enabled
378-
}
379-
mediaManager.audioTrack.trySetEnabled(true)
369+
enforceSetup {
370+
if (fromUser) {
371+
_status.value = DeviceStatus.Enabled
380372
}
373+
mediaManager.audioTrack.trySetEnabled(true)
381374
}
382375
}
383376

@@ -562,21 +555,15 @@ public class CameraManager(
562555
}
563556

564557
internal fun enable(fromUser: Boolean = true) {
565-
val (isCallVideoEnabled, canUserSendVideo) = with(mediaManager.call.state) {
566-
(settings.value?.video?.enabled == true) to ownCapabilities.value.contains(OwnCapability.SendVideo)
567-
}
568-
569-
if (isCallVideoEnabled && canUserSendVideo) {
570-
setup()
571-
// 1. update our local state
572-
// 2. update the track enabled status
573-
// 3. Rtc listens and sends the update mute state request
574-
if (fromUser) {
575-
_status.value = DeviceStatus.Enabled
576-
}
577-
mediaManager.videoTrack.trySetEnabled(true)
578-
startCapture()
558+
setup()
559+
// 1. update our local state
560+
// 2. update the track enabled status
561+
// 3. Rtc listens and sends the update mute state request
562+
if (fromUser) {
563+
_status.value = DeviceStatus.Enabled
579564
}
565+
mediaManager.videoTrack.trySetEnabled(true)
566+
startCapture()
580567
}
581568

582569
fun pause(fromUser: Boolean = true) {

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/call/RtcSession.kt

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import android.os.PowerManager.THERMAL_STATUS_SEVERE
2727
import android.os.PowerManager.THERMAL_STATUS_SHUTDOWN
2828
import androidx.annotation.VisibleForTesting
2929
import androidx.lifecycle.Lifecycle
30+
import io.getstream.android.video.generated.models.OwnCapability
3031
import io.getstream.android.video.generated.models.VideoEvent
3132
import io.getstream.log.taggedLogger
3233
import io.getstream.result.Result
@@ -49,7 +50,6 @@ import io.getstream.video.android.core.call.utils.TrackOverridesHandler
4950
import io.getstream.video.android.core.call.utils.stringify
5051
import io.getstream.video.android.core.dispatchers.DispatcherProvider
5152
import io.getstream.video.android.core.errors.RtcException
52-
import io.getstream.video.android.core.events.CallEndedSfuEvent
5353
import io.getstream.video.android.core.events.ChangePublishOptionsEvent
5454
import io.getstream.video.android.core.events.ChangePublishQualityEvent
5555
import io.getstream.video.android.core.events.ICERestartEvent
@@ -439,10 +439,6 @@ public class RtcSession internal constructor(
439439
// listen to socket events and errors
440440
eventJob = coroutineScope.launch {
441441
sfuConnectionModule.socketConnection.events().collect {
442-
if (it is CallEndedSfuEvent) {
443-
logger.d { "#rtcsession #events #sfu, event: $it" }
444-
call.leave()
445-
}
446442
clientImpl.fireEvent(it, call.cid)
447443
}
448444
}
@@ -562,72 +558,91 @@ public class RtcSession internal constructor(
562558
listenToSfuSocket()
563559
}
564560

565-
private suspend fun listenToMediaChanges() {
561+
private fun listenToMediaChanges() {
566562
coroutineScope.launch {
567563
// update the tracks when the camera or microphone status changes
568564
call.mediaManager.camera.status.collectLatest {
569-
// set the mute /unumute status
570-
setMuteState(isEnabled = it == DeviceStatus.Enabled, TrackType.TRACK_TYPE_VIDEO)
565+
val canUserSendVideo = call.state.ownCapabilities.value.contains(
566+
OwnCapability.SendVideo,
567+
)
571568

572569
if (it == DeviceStatus.Enabled) {
573-
val track = publisher?.publishStream(
574-
TrackType.TRACK_TYPE_VIDEO,
575-
call.mediaManager.camera.resolution.value,
576-
)
577-
setLocalTrack(
578-
TrackType.TRACK_TYPE_VIDEO,
579-
VideoTrack(
580-
streamId = buildTrackId(TrackType.TRACK_TYPE_VIDEO),
581-
video = track as org.webrtc.VideoTrack,
582-
),
583-
)
570+
if (canUserSendVideo) {
571+
setMuteState(isEnabled = true, TrackType.TRACK_TYPE_VIDEO)
572+
573+
val track = publisher?.publishStream(
574+
TrackType.TRACK_TYPE_VIDEO,
575+
call.mediaManager.camera.resolution.value,
576+
)
577+
578+
setLocalTrack(
579+
TrackType.TRACK_TYPE_VIDEO,
580+
VideoTrack(
581+
streamId = buildTrackId(TrackType.TRACK_TYPE_VIDEO),
582+
video = track as org.webrtc.VideoTrack,
583+
),
584+
)
585+
}
584586
} else {
587+
setMuteState(isEnabled = false, TrackType.TRACK_TYPE_VIDEO)
585588
publisher?.unpublishStream(TrackType.TRACK_TYPE_VIDEO)
586589
}
587590
}
588591
}
589592

590593
coroutineScope.launch {
591594
call.mediaManager.microphone.status.collectLatest {
592-
// set the mute /unumute status
593-
setMuteState(isEnabled = it == DeviceStatus.Enabled, TrackType.TRACK_TYPE_AUDIO)
595+
val canUserSendAudio = call.state.ownCapabilities.value.contains(
596+
OwnCapability.SendAudio,
597+
)
594598

595599
if (it == DeviceStatus.Enabled) {
596-
val track = publisher?.publishStream(
597-
TrackType.TRACK_TYPE_AUDIO,
598-
)
599-
setLocalTrack(
600-
TrackType.TRACK_TYPE_AUDIO,
601-
AudioTrack(
602-
streamId = buildTrackId(TrackType.TRACK_TYPE_AUDIO),
603-
audio = track as org.webrtc.AudioTrack,
604-
),
605-
)
600+
if (canUserSendAudio) {
601+
setMuteState(isEnabled = true, TrackType.TRACK_TYPE_AUDIO)
602+
603+
val track = publisher?.publishStream(
604+
TrackType.TRACK_TYPE_AUDIO,
605+
)
606+
607+
setLocalTrack(
608+
TrackType.TRACK_TYPE_AUDIO,
609+
AudioTrack(
610+
streamId = buildTrackId(TrackType.TRACK_TYPE_AUDIO),
611+
audio = track as org.webrtc.AudioTrack,
612+
),
613+
)
614+
}
606615
} else {
616+
setMuteState(isEnabled = false, TrackType.TRACK_TYPE_AUDIO)
607617
publisher?.unpublishStream(TrackType.TRACK_TYPE_AUDIO)
608618
}
609619
}
610620
}
611621

612622
coroutineScope.launch {
613623
call.mediaManager.screenShare.status.collectLatest {
614-
// set the mute /unumute status
615-
setMuteState(
616-
isEnabled = it == DeviceStatus.Enabled,
617-
TrackType.TRACK_TYPE_SCREEN_SHARE,
624+
val canUserShareScreen = call.state.ownCapabilities.value.contains(
625+
OwnCapability.Screenshare,
618626
)
627+
619628
if (it == DeviceStatus.Enabled) {
620-
val track = publisher?.publishStream(
621-
TrackType.TRACK_TYPE_SCREEN_SHARE,
622-
)
623-
setLocalTrack(
624-
TrackType.TRACK_TYPE_SCREEN_SHARE,
625-
VideoTrack(
626-
streamId = buildTrackId(TrackType.TRACK_TYPE_SCREEN_SHARE),
627-
video = track as org.webrtc.VideoTrack,
628-
),
629-
)
629+
if (canUserShareScreen) {
630+
setMuteState(true, TrackType.TRACK_TYPE_SCREEN_SHARE)
631+
632+
val track = publisher?.publishStream(
633+
TrackType.TRACK_TYPE_SCREEN_SHARE,
634+
)
635+
636+
setLocalTrack(
637+
TrackType.TRACK_TYPE_SCREEN_SHARE,
638+
VideoTrack(
639+
streamId = buildTrackId(TrackType.TRACK_TYPE_SCREEN_SHARE),
640+
video = track as org.webrtc.VideoTrack,
641+
),
642+
)
643+
}
630644
} else {
645+
setMuteState(false, TrackType.TRACK_TYPE_SCREEN_SHARE)
631646
publisher?.unpublishStream(TrackType.TRACK_TYPE_SCREEN_SHARE)
632647
}
633648
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/call/connection/StreamPeerConnectionFactory.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ import io.getstream.log.taggedLogger
2323
import io.getstream.video.android.core.MediaManagerImpl
2424
import io.getstream.video.android.core.ParticipantState
2525
import io.getstream.video.android.core.api.SignalServerService
26+
import io.getstream.video.android.core.call.connection.coding.SelectiveVideoDecoderFactory
2627
import io.getstream.video.android.core.call.video.FilterVideoProcessor
2728
import io.getstream.video.android.core.defaultAudioUsage
2829
import io.getstream.video.android.core.model.IceCandidate
2930
import io.getstream.video.android.core.model.StreamPeerType
3031
import kotlinx.coroutines.CoroutineScope
3132
import org.webrtc.AudioSource
3233
import org.webrtc.AudioTrack
33-
import org.webrtc.DefaultBlacklistedVideoDecoderFactory
3434
import org.webrtc.EglBase
3535
import org.webrtc.Logging
3636
import org.webrtc.ManagedAudioProcessingFactory
@@ -107,7 +107,7 @@ public class StreamPeerConnectionFactory(
107107
* Default video decoder factory used to unpack video from the remote tracks.
108108
*/
109109
private val videoDecoderFactory by lazy {
110-
DefaultBlacklistedVideoDecoderFactory(eglBase.eglBaseContext)
110+
SelectiveVideoDecoderFactory(eglBase.eglBaseContext)
111111
}
112112

113113
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2014-2024 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-video-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.video.android.core.call.connection.coding
18+
19+
import org.webrtc.EglBase
20+
import org.webrtc.SoftwareVideoDecoderFactory
21+
import org.webrtc.VideoCodecInfo
22+
import org.webrtc.VideoDecoder
23+
import org.webrtc.VideoDecoderFactory
24+
import org.webrtc.WrappedVideoDecoderFactory
25+
26+
internal class SelectiveVideoDecoderFactory(
27+
sharedContext: EglBase.Context?,
28+
private var forceSWCodec: Boolean = false,
29+
private var forceSWCodecs: List<String> = listOf("VP9", "AV1"),
30+
) : VideoDecoderFactory {
31+
private val softwareVideoDecoderFactory = SoftwareVideoDecoderFactory()
32+
private val wrappedVideoDecoderFactory = WrappedVideoDecoderFactory(sharedContext)
33+
34+
/**
35+
* Set to true to force software codecs.
36+
*/
37+
fun setForceSWCodec(forceSWCodec: Boolean) {
38+
this.forceSWCodec = forceSWCodec
39+
}
40+
41+
/**
42+
* Set a list of codecs for which to use software codecs.
43+
*/
44+
fun setForceSWCodecList(forceSWCodecs: List<String>) {
45+
this.forceSWCodecs = forceSWCodecs
46+
}
47+
48+
override fun createDecoder(videoCodecInfo: VideoCodecInfo): VideoDecoder? {
49+
if (forceSWCodec) {
50+
return softwareVideoDecoderFactory.createDecoder(videoCodecInfo)
51+
}
52+
if (forceSWCodecs.isNotEmpty()) {
53+
if (forceSWCodecs.contains(videoCodecInfo.name)) {
54+
return softwareVideoDecoderFactory.createDecoder(videoCodecInfo)
55+
}
56+
}
57+
return wrappedVideoDecoderFactory.createDecoder(videoCodecInfo)
58+
}
59+
60+
override fun getSupportedCodecs(): Array<VideoCodecInfo> {
61+
return if (forceSWCodec && forceSWCodecs.isEmpty()) {
62+
softwareVideoDecoderFactory.supportedCodecs
63+
} else {
64+
wrappedVideoDecoderFactory.supportedCodecs
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)