Commit 0dd9fb63 authored by wez@chromium.org's avatar wez@chromium.org

Add support for I444 frames to VideoDecoderVpx.

VideoDecoderVpx has supported VP9 for a while, but was missing a colour
conversion codepath from I444 frames to ARGB.

BUG=377239,260879,134202

Review URL: https://codereview.chromium.org/300653002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272846 0039d316-1c4b-4281-b951-d872f2087c98
parent f56c9ae1
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "media/base/media.h" #include "media/base/media.h"
#include "media/base/yuv_convert.h" #include "media/base/yuv_convert.h"
#include "remoting/base/util.h" #include "remoting/base/util.h"
#include "third_party/libyuv/include/libyuv/convert_argb.h"
extern "C" { extern "C" {
#define VPX_CODEC_DISABLE_COMPAT 1 #define VPX_CODEC_DISABLE_COMPAT 1
...@@ -177,10 +178,46 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size, ...@@ -177,10 +178,46 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size,
webrtc::DesktopRect source_clip = webrtc::DesktopRect source_clip =
webrtc::DesktopRect::MakeWH(last_image_->d_w, last_image_->d_h); webrtc::DesktopRect::MakeWH(last_image_->d_w, last_image_->d_h);
// ScaleYUVToRGB32WithRect does not currently support up-scaling. We won't // VP8 only outputs I420 frames, but VP9 can also produce I444.
// be asked to up-scale except during resizes or if page zoom is >100%, so switch (last_image_->fmt) {
// we work-around the limitation by using the slower ScaleYUVToRGB32. case VPX_IMG_FMT_I444: {
// TODO(wez): Remove this hack if/when ScaleYUVToRGB32WithRect can up-scale. // TODO(wez): Add scaling support to the I444 conversion path.
if (view_size.equals(screen_size_)) {
for (webrtc::DesktopRegion::Iterator i(updated_region_);
!i.IsAtEnd(); i.Advance()) {
// Determine the scaled area affected by this rectangle changing.
webrtc::DesktopRect rect = i.rect();
rect.IntersectWith(source_clip);
rect.IntersectWith(clip_area);
if (rect.is_empty())
continue;
int image_offset = image_stride * rect.top() +
rect.left() * VideoDecoder::kBytesPerPixel;
int y_offset = last_image_->stride[0] * rect.top() + rect.left();
int u_offset = last_image_->stride[1] * rect.top() + rect.left();
int v_offset = last_image_->stride[2] * rect.top() + rect.left();
libyuv::I444ToARGB(last_image_->planes[0] + y_offset,
last_image_->stride[0],
last_image_->planes[1] + u_offset,
last_image_->stride[1],
last_image_->planes[2] + v_offset,
last_image_->stride[2],
image_buffer + image_offset, image_stride,
rect.width(), rect.height());
output_region->AddRect(rect);
}
}
break;
}
case VPX_IMG_FMT_I420: {
// ScaleYUVToRGB32WithRect does not currently support up-scaling. We
// won't be asked to up-scale except during resizes or if page zoom is
// >100%, so we work-around the limitation by using the slower
// ScaleYUVToRGB32.
// TODO(wez): Remove this hack if/when ScaleYUVToRGB32WithRect can
// up-scale.
if (!updated_region_.is_empty() && if (!updated_region_.is_empty() &&
(source_clip.width() < view_size.width() || (source_clip.width() < view_size.width() ||
source_clip.height() < view_size.height())) { source_clip.height() < view_size.height())) {
...@@ -194,7 +231,8 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size, ...@@ -194,7 +231,8 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size,
source_rect.right(), source_rect.right(),
source_rect.bottom()); source_rect.bottom());
// If there were no changes within the clip source area then don't render. // If there were no changes within the clip source area then don't
// render.
webrtc::DesktopRegion intersection(source_rect); webrtc::DesktopRegion intersection(source_rect);
intersection.IntersectWith(updated_region_); intersection.IntersectWith(updated_region_);
if (intersection.is_empty()) if (intersection.is_empty())
...@@ -254,6 +292,13 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size, ...@@ -254,6 +292,13 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size,
} }
updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_)); updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_));
break;
}
default: {
LOG(ERROR) << "Unsupported image format:" << last_image_->fmt;
return;
}
}
for (webrtc::DesktopRegion::Iterator i(transparent_region_); for (webrtc::DesktopRegion::Iterator i(transparent_region_);
!i.IsAtEnd(); i.Advance()) { !i.IsAtEnd(); i.Advance()) {
......
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