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:
@@ -159,6 +159,9 @@ class VideoDimensions {
|
|||||||
/// Returns the larger value
|
/// Returns the larger value
|
||||||
int max() => math.max(width, height);
|
int max() => math.max(width, height);
|
||||||
|
|
||||||
|
/// Returns the smaller value
|
||||||
|
int min() => math.min(width, height);
|
||||||
|
|
||||||
VideoDimensions copyWith({
|
VideoDimensions copyWith({
|
||||||
int? width,
|
int? width,
|
||||||
int? height,
|
int? height,
|
||||||
|
|||||||
+27
-3
@@ -231,18 +231,42 @@ class Utils {
|
|||||||
if (i >= videoRids.length) {
|
if (i >= videoRids.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final size = dimensions.max();
|
|
||||||
final encodingSize = e.dimensions.max();
|
|
||||||
final rid = videoRids[i];
|
final rid = videoRids[i];
|
||||||
|
|
||||||
result.add(e.encoding.toRTCRtpEncoding(
|
result.add(e.encoding.toRTCRtpEncoding(
|
||||||
rid: rid,
|
rid: rid,
|
||||||
scaleResolutionDownBy: size / encodingSize,
|
scaleResolutionDownBy: findEvenScaleDownBy(dimensions, e.dimensions),
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
return result;
|
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
|
@internal
|
||||||
static List<rtc.RTCRtpEncoding>? computeVideoEncodings({
|
static List<rtc.RTCRtpEncoding>? computeVideoEncodings({
|
||||||
required bool isScreenShare,
|
required bool isScreenShare,
|
||||||
|
|||||||
Reference in New Issue
Block a user