Ensure even video dimensions (#82)

gotcha, I think we may have to do some work iOS later to properly grab the actual capture dimensions rather than rely on the dimensions we request, to properly do the calculations.

That said, I think m97 is now handling the odd dimensions properly, so I don't think we'll need this fix anymore.

As for adaptOutputFormat, flutter_webrtc is already doing that (though it doesn't seem to prevent the crash on m93). Should native android use this as well?
This commit is contained in:
davidliu
2022-02-16 01:15:41 +09:00
committed by GitHub
parent a2e8643ebb
commit c374283f45
2 changed files with 30 additions and 3 deletions
+3
View File
@@ -159,6 +159,9 @@ class VideoDimensions {
/// Returns the larger value
int max() => math.max(width, height);
/// Returns the smaller value
int min() => math.min(width, height);
VideoDimensions copyWith({
int? width,
int? height,
+27 -3
View File
@@ -231,18 +231,42 @@ class Utils {
if (i >= videoRids.length) {
return;
}
final size = dimensions.max();
final encodingSize = e.dimensions.max();
final rid = videoRids[i];
result.add(e.encoding.toRTCRtpEncoding(
rid: rid,
scaleResolutionDownBy: size / encodingSize,
scaleResolutionDownBy: findEvenScaleDownBy(dimensions, e.dimensions),
));
});
return result;
}
@internal
static double findEvenScaleDownBy(
VideoDimensions sourceDimensions,
VideoDimensions targetDimensions,
) {
bool isEven(int v) => v % 2 == 0;
final sourceSize = sourceDimensions.max();
final targetSize = targetDimensions.max();
for (int i = 0; i <= 30; i++) {
final scaleDownBy = sourceSize.toDouble() / (targetSize + i);
// Internally, WebRTC casts directly to int without rounding.
// https://github.com/webrtc-sdk/webrtc/blob/8c7139f8e6fa19ddf2c91510c177a19746e1ded3/media/engine/webrtc_video_engine.cc#L3676
final scaledWidth = sourceDimensions.width ~/ scaleDownBy;
final scaledHeight = sourceDimensions.height ~/ scaleDownBy;
if (isEven(scaledWidth) && isEven(scaledHeight)) {
return scaleDownBy;
}
}
// couldn't find an even scale, just return original scale and hope it works.
return sourceSize / targetSize;
}
@internal
static List<rtc.RTCRtpEncoding>? computeVideoEncodings({
required bool isScreenShare,