Commit cfdc9101 authored by Miguel Casas's avatar Miguel Casas Committed by Commit Bot

MediaStream: don't produce VideoFrames w/ odd dimensions

MSTrack.applyConstraints() produces sometimes odd-dimension frames due
to rounding errors. This is a problem for texture-backed VideoFrames.
This CL avoids that by producing a |visible_rect| of even size and
fully enclosed in the original frame.

I tested this on a nocturne chromebook, with the FakeVCD, navigating to
[1] and changing the resolution slider a number of times. This would
mess up ToT graphics; with the patch, it's fixed.

[1] https://webrtc.github.io/samples/src/content/getusermedia/resolution/

Bug: 1045261
Change-Id: I3734ae68a485342195601f15892389793372eed7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2017918Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Reviewed-by: default avatarJohn Rummell <jrummell@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Auto-Submit: Miguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735023}
parent 13b03208
...@@ -458,6 +458,12 @@ TEST_F(VideoUtilTest, ComputeLetterboxRegion) { ...@@ -458,6 +458,12 @@ TEST_F(VideoUtilTest, ComputeLetterboxRegion) {
gfx::Size(40000, 30000))); gfx::Size(40000, 30000)));
EXPECT_TRUE(ComputeLetterboxRegion(gfx::Rect(0, 0, 2000000000, 2000000000), EXPECT_TRUE(ComputeLetterboxRegion(gfx::Rect(0, 0, 2000000000, 2000000000),
gfx::Size(0, 0)).IsEmpty()); gfx::Size(0, 0)).IsEmpty());
// Some operations in the internal ScaleSizeToTarget() use rounded division
// and might lose some precision, this expectation codifies that.
EXPECT_EQ(
gfx::Rect(0, 0, 1279, 720),
ComputeLetterboxRegion(gfx::Rect(0, 0, 1280, 720), gfx::Size(1057, 595)));
} }
// Tests the ComputeLetterboxRegionForI420 function. // Tests the ComputeLetterboxRegionForI420 function.
......
...@@ -342,9 +342,17 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( ...@@ -342,9 +342,17 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame(
// |desired_size| that fits entirely inside of |frame->visible_rect()|. // |desired_size| that fits entirely inside of |frame->visible_rect()|.
// This will be the rect we need to crop the original frame to. // This will be the rect we need to crop the original frame to.
// From this rect, the original frame can be scaled down to |desired_size|. // From this rect, the original frame can be scaled down to |desired_size|.
const gfx::Rect region_in_frame = gfx::Rect region_in_frame =
media::ComputeLetterboxRegion(frame->visible_rect(), desired_size); media::ComputeLetterboxRegion(frame->visible_rect(), desired_size);
if (frame->HasTextures() || frame->HasGpuMemoryBuffer()) {
// ComputeLetterboxRegion() produces in some cases odd dimensions due to
// internal rounding errors; |region_in_frame| is always smaller or equal
// to frame->visible_rect(), we can "grow it" if the dimensions are odd.
region_in_frame.set_width((region_in_frame.width() + 1) & ~1);
region_in_frame.set_height((region_in_frame.height() + 1) & ~1);
}
video_frame = media::VideoFrame::WrapVideoFrame( video_frame = media::VideoFrame::WrapVideoFrame(
frame, frame->format(), region_in_frame, desired_size); frame, frame->format(), region_in_frame, desired_size);
if (!video_frame) { if (!video_frame) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment