diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-03 21:57:35 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-03 21:57:35 +0000 |
commit | 32da100526eadc7d8f2d97753a48f5917bb17c66 (patch) | |
tree | dc03272f2019998ac021f422cff6e9b104223958 /webkit | |
parent | b1fa235f89f443ca06c36727257323227be979b0 (diff) | |
download | chromium_src-32da100526eadc7d8f2d97753a48f5917bb17c66.zip chromium_src-32da100526eadc7d8f2d97753a48f5917bb17c66.tar.gz chromium_src-32da100526eadc7d8f2d97753a48f5917bb17c66.tar.bz2 |
Fix low quality scaling of <video> on mac
BUG=35534
TEST=Use sample in http://crbug.com/35534
Fixing bug 35534 of image quality if CSS scaling is applied
to a <video> tag.
On mac we currently create an image the same size of the width
and height attribute of the <video> tag regardless of the
transformation matrix of the canvas. If we use the scaling factor
in the transformation matrix and use it directly in the YUV
to RGB conversion, not only we solve the problem of low quality
image scaling but performance is also improved.
Review URL: http://codereview.chromium.org/660435
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40546 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/webmediaplayer_impl.cc | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index 8dd46b5..c85d6d0 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -6,6 +6,7 @@ #include "base/callback.h" #include "base/command_line.h" +#include "media/base/limits.h" #include "media/base/media_format.h" #include "media/base/media_switches.h" #include "media/filters/ffmpeg_audio_decoder.h" @@ -481,17 +482,34 @@ void WebMediaPlayerImpl::paint(WebCanvas* canvas, #if WEBKIT_USING_SKIA proxy_->Paint(canvas, rect); #elif WEBKIT_USING_CG + // Get the current scaling in X and Y. + CGAffineTransform mat = CGContextGetCTM(canvas); + float scale_x = sqrt(mat.a * mat.a + mat.b * mat.b); + float scale_y = sqrt(mat.c * mat.c + mat.d * mat.d); + float inverse_scale_x = SkScalarNearlyZero(scale_x) ? 0.0f : 1.0f / scale_x; + float inverse_scale_y = SkScalarNearlyZero(scale_y) ? 0.0f : 1.0f / scale_y; + int scaled_width = static_cast<int>(rect.width * fabs(scale_x)); + int scaled_height = static_cast<int>(rect.height * fabs(scale_y)); + + // Make sure we don't create a huge canvas. + // TODO(hclam): Respect the aspect ratio. + if (scaled_width > static_cast<int>(media::Limits::kMaxCanvas)) + scaled_width = media::Limits::kMaxCanvas; + if (scaled_height > static_cast<int>(media::Limits::kMaxCanvas)) + scaled_height = media::Limits::kMaxCanvas; + // If there is no preexisting platform canvas, or if the size has // changed, recreate the canvas. This is to avoid recreating the bitmap // buffer over and over for each frame of video. if (!skia_canvas_.get() || - skia_canvas_->getDevice()->width() != rect.width || - skia_canvas_->getDevice()->height() != rect.height) { - skia_canvas_.reset(new skia::PlatformCanvas(rect.width, rect.height, true)); + skia_canvas_->getDevice()->width() != scaled_width || + skia_canvas_->getDevice()->height() != scaled_height) { + skia_canvas_.reset( + new skia::PlatformCanvas(scaled_width, scaled_height, true)); } // Draw to our temporary skia canvas. - gfx::Rect normalized_rect(rect.width, rect.height); + gfx::Rect normalized_rect(scaled_width, scaled_height); proxy_->Paint(skia_canvas_.get(), normalized_rect); // The mac coordinate system is flipped vertical from the normal skia @@ -500,7 +518,7 @@ void WebMediaPlayerImpl::paint(WebCanvas* canvas, // start at 0,0. CGContextSaveGState(canvas); CGContextTranslateCTM(canvas, rect.x, rect.height + rect.y); - CGContextScaleCTM(canvas, 1.0, -1.0); + CGContextScaleCTM(canvas, inverse_scale_x, -inverse_scale_y); // We need a local variable CGRect version for DrawToContext. CGRect normalized_cgrect = |