Prevent constantly requesting new video resolutions in group calls.

This commit is contained in:
Cody Henthorne 2021-08-13 09:28:43 -04:00
parent 0c6fe8bea3
commit 8802cebb64
5 changed files with 42 additions and 18 deletions

View file

@ -71,6 +71,7 @@ import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.EllapsedTimeFormatter;
import org.thoughtcrime.securesms.util.FullscreenHelper;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ThrottledDebouncer;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.thoughtcrime.securesms.webrtc.CallParticipantsViewState;
@ -79,6 +80,7 @@ import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import static org.thoughtcrime.securesms.components.sensors.Orientation.PORTRAIT_BOTTOM_EDGE;
@ -104,6 +106,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
private boolean enableVideoIfAvailable;
private androidx.window.WindowManager windowManager;
private WindowLayoutInfoConsumer windowLayoutInfoConsumer;
private ThrottledDebouncer requestNewSizesThrottle;
@Override
protected void attachBaseContext(@NonNull Context newBase) {
@ -143,6 +146,8 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
windowLayoutInfoConsumer = new WindowLayoutInfoConsumer();
windowManager.registerLayoutChangeCallback(SignalExecutors.BOUNDED, windowLayoutInfoConsumer);
requestNewSizesThrottle = new ThrottledDebouncer(TimeUnit.SECONDS.toMillis(1));
}
@Override
@ -187,6 +192,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
if (!isInPipMode() || isFinishing()) {
EventBus.getDefault().unregister(this);
requestNewSizesThrottle.clear();
}
if (!viewModel.isCallStarting()) {
@ -297,7 +303,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
CallParticipantsState state = viewModel.getCallParticipantsState().getValue();
if (state != null) {
if (state.needsNewRequestSizes()) {
ApplicationDependencies.getSignalCallManager().updateRenderedResolutions();
requestNewSizesThrottle.publish(() -> ApplicationDependencies.getSignalCallManager().updateRenderedResolutions());
}
}
});

View file

@ -3,12 +3,11 @@ package org.thoughtcrime.securesms.components.webrtc;
import android.graphics.Point;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.webrtc.EglBase;
import org.webrtc.VideoFrame;
import org.webrtc.VideoSink;
import java.util.Objects;
import java.util.WeakHashMap;
/**
@ -25,11 +24,11 @@ public class BroadcastVideoSink implements VideoSink {
private final EglBaseWrapper eglBase;
private final WeakHashMap<VideoSink, Boolean> sinks;
private final WeakHashMap<Object, Point> requestingSizes;
private boolean dirtySizes;
private int deviceOrientationDegrees;
private boolean rotateToRightSide;
private boolean forceRotate;
private boolean rotateWithDevice;
private RequestedSize currentlyRequestedMaxSize;
public BroadcastVideoSink() {
this(new EglBaseWrapper(null), false, true, 0);
@ -45,7 +44,6 @@ public class BroadcastVideoSink implements VideoSink {
this.eglBase = eglBase;
this.sinks = new WeakHashMap<>();
this.requestingSizes = new WeakHashMap<>();
this.dirtySizes = true;
this.deviceOrientationDegrees = deviceOrientationDegrees;
this.rotateToRightSide = false;
this.forceRotate = forceRotate;
@ -120,16 +118,18 @@ public class BroadcastVideoSink implements VideoSink {
}
void putRequestingSize(@NonNull Object object, @NonNull Point size) {
if (size.x == 0 || size.y == 0) {
return;
}
synchronized (requestingSizes) {
requestingSizes.put(object, size);
dirtySizes = true;
}
}
void removeRequestingSize(@NonNull Object object) {
synchronized (requestingSizes) {
requestingSizes.remove(object);
dirtySizes = true;
}
}
@ -149,15 +149,15 @@ public class BroadcastVideoSink implements VideoSink {
return new RequestedSize(width, height);
}
public void newSizeRequested() {
dirtySizes = false;
public void setCurrentlyRequestedMaxSize(@NonNull RequestedSize currentlyRequestedMaxSize) {
this.currentlyRequestedMaxSize = currentlyRequestedMaxSize;
}
public boolean needsNewRequestingSize() {
return dirtySizes;
return !getMaxRequestingSize().equals(currentlyRequestedMaxSize);
}
public static class RequestedSize {
public static final class RequestedSize {
private final int width;
private final int height;
@ -173,5 +173,19 @@ public class BroadcastVideoSink implements VideoSink {
public int getHeight() {
return height;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final RequestedSize that = (RequestedSize) o;
return width == that.width && height == that.height;
}
@Override
public int hashCode() {
return Objects.hash(width, height);
}
}
}

View file

@ -187,8 +187,6 @@ public class TextureViewRenderer extends TextureView implements TextureView.Surf
setMeasuredDimension(size.x, size.y);
Log.d(TAG, "onMeasure(). New size: " + size.x + "x" + size.y);
if (attachedVideoSink != null) {
attachedVideoSink.putRequestingSize(this, size);
}

View file

@ -173,7 +173,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
BroadcastVideoSink.RequestedSize maxSize = videoSink.getMaxRequestingSize();
resolutionRequests.add(new GroupCall.VideoRequest(entry.getKey().getDemuxId(), maxSize.getWidth(), maxSize.getHeight(), null));
videoSink.newSizeRequested();
videoSink.setCurrentlyRequestedMaxSize(maxSize);
}
try {

View file

@ -38,12 +38,16 @@ public class ThrottledDebouncer {
@MainThread
public void publish(Runnable runnable) {
handler.setRunnable(runnable);
if (handler.hasMessages(WHAT)) {
handler.setRunnable(runnable);
} else {
runnable.run();
handler.sendMessageDelayed(handler.obtainMessage(WHAT), threshold);
return;
}
long sinceLastRun = System.currentTimeMillis() - handler.lastRun;
long delay = Math.max(0, threshold - sinceLastRun);
handler.sendMessageDelayed(handler.obtainMessage(WHAT), delay);
}
@MainThread
@ -58,10 +62,12 @@ public class ThrottledDebouncer {
}
private Runnable runnable;
private long lastRun = 0;
@Override
public void handleMessage(Message msg) {
if (msg.what == WHAT && runnable != null) {
lastRun = System.currentTimeMillis();
runnable.run();
runnable = null;
}