Bug 1453826 - P1 - screen share scale aspect ratio
MozReview-Commit-ID: LSce4YaUoDP
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -476,16 +476,49 @@ MediaEngineRemoteVideoSource::Pull(const
// This is safe from any thread, and is safe if the track is Finished
// or Destroyed.
// This can fail if either a) we haven't added the track yet, or b)
// we've removed or finished the track.
aStream->AppendToTrack(aTrackID, &segment);
}
+// Translate screen share aspect ratio to constraint aspect ratio if only a
+// single dimension constraint is supplied.
+inline void
+preserveScreenShareAspectRatio(int32_t& aConstraintWidth,
+ int32_t& aConstraintHeight,
+ const camera::VideoFrameProperties& aProps)
+{
+ if ((aConstraintHeight && aConstraintWidth) ||
+ (!aConstraintWidth && !aConstraintHeight) ||
+ !aProps.height() || !aProps.width()) {
+ return;
+ }
+ int32_t gcd = EuclidGCD(aProps.width(), aProps.height());
+ int32_t minWidth = aProps.width() / gcd;
+ int32_t minHeight = aProps.height() / gcd;
+ MOZ_ASSERT(minWidth && minHeight);
+ if (aConstraintHeight) {
+ // Clamp height to multiple of the unit height
+ aConstraintHeight -= (aConstraintHeight % minHeight);
+ // Apply aspect ratio in unit widths
+ aConstraintWidth = minWidth * aConstraintHeight / minHeight;
+ } else {
+ // Clamp width to multiple of the unit width
+ aConstraintWidth -= (aConstraintWidth % minWidth);
+ // Apply aspect ratio in unit heights
+ aConstraintHeight = minHeight * aConstraintWidth / minWidth;
+ }
+ if (aConstraintWidth < minWidth || aConstraintHeight < minHeight) {
+ aConstraintHeight = minHeight;
+ aConstraintWidth = minWidth;
+ }
+}
+
int
MediaEngineRemoteVideoSource::DeliverFrame(uint8_t* aBuffer,
const camera::VideoFrameProperties& aProps)
{
// Cameras IPC thread - take great care with accessing members!
int32_t req_max_width;
int32_t req_max_height;
@@ -494,17 +527,31 @@ MediaEngineRemoteVideoSource::DeliverFra
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mState == kStarted);
req_max_width = mCapability.width & 0xffff;
req_max_height = mCapability.height & 0xffff;
req_ideal_width = (mCapability.width >> 16) & 0xffff;
req_ideal_height = (mCapability.height >> 16) & 0xffff;
}
-
+ // See bug Bug 1453269
+ switch (mMediaSource) {
+ case MediaSourceEnum::Screen:
+ case MediaSourceEnum::Window:
+ case MediaSourceEnum::Application: {
+ // Preserve aspect ratio for screen sharing if only a single dimension
+ // is supplied.
+ preserveScreenShareAspectRatio(req_max_width, req_max_height, aProps);
+ preserveScreenShareAspectRatio(req_ideal_width, req_ideal_height, aProps);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
if (aProps.rotation() == 90 || aProps.rotation() == 270) {
// This frame is rotated, so what was negotiated as width is now height,
// and vice versa.
std::swap(req_max_width, req_max_height);
std::swap(req_ideal_width, req_ideal_height);
}
int32_t dst_max_width = std::min(req_max_width, aProps.width());