Chromium Code Reviews| Index: remoting/codec/video_decoder_vpx.cc |
| diff --git a/remoting/codec/video_decoder_vpx.cc b/remoting/codec/video_decoder_vpx.cc |
| index e414ee8e5e7a026c9e35a6351b16881c4259c19c..b0e3029c450515aeba7d231c5271ef95bc3c57aa 100644 |
| --- a/remoting/codec/video_decoder_vpx.cc |
| +++ b/remoting/codec/video_decoder_vpx.cc |
| @@ -12,6 +12,7 @@ |
| #include "media/base/media.h" |
| #include "media/base/yuv_convert.h" |
| #include "remoting/base/util.h" |
| +#include "third_party/libyuv/include/libyuv/convert_argb.h" |
| extern "C" { |
| #define VPX_CODEC_DISABLE_COMPAT 1 |
| @@ -177,84 +178,128 @@ void VideoDecoderVpx::RenderFrame(const webrtc::DesktopSize& view_size, |
| webrtc::DesktopRect source_clip = |
| webrtc::DesktopRect::MakeWH(last_image_->d_w, last_image_->d_h); |
| - // 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() && |
| - (source_clip.width() < view_size.width() || |
| - source_clip.height() < view_size.height())) { |
| - // We're scaling only |clip_area| into the |image_buffer|, so we need to |
| - // work out which source rectangle that corresponds to. |
| - webrtc::DesktopRect source_rect = |
| - ScaleRect(clip_area, view_size, screen_size_); |
| - source_rect = webrtc::DesktopRect::MakeLTRB( |
| - RoundToTwosMultiple(source_rect.left()), |
| - RoundToTwosMultiple(source_rect.top()), |
| - source_rect.right(), |
| - source_rect.bottom()); |
| - |
| - // If there were no changes within the clip source area then don't render. |
| - webrtc::DesktopRegion intersection(source_rect); |
| - intersection.IntersectWith(updated_region_); |
| - if (intersection.is_empty()) |
| + // VP8 only outputs I420 frames, but VP9 can also produce I444. |
| + switch (last_image_->fmt) { |
| + case VPX_IMG_FMT_I444: { |
| + // 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() && |
| + (source_clip.width() < view_size.width() || |
| + source_clip.height() < view_size.height())) { |
| + // We're scaling only |clip_area| into the |image_buffer|, so we need to |
| + // work out which source rectangle that corresponds to. |
| + webrtc::DesktopRect source_rect = |
| + ScaleRect(clip_area, view_size, screen_size_); |
| + source_rect = webrtc::DesktopRect::MakeLTRB( |
| + RoundToTwosMultiple(source_rect.left()), |
| + RoundToTwosMultiple(source_rect.top()), |
| + source_rect.right(), |
| + source_rect.bottom()); |
| + |
| + // If there were no changes within the clip source area then don't |
| + // render. |
| + webrtc::DesktopRegion intersection(source_rect); |
| + intersection.IntersectWith(updated_region_); |
| + if (intersection.is_empty()) |
| + return; |
| + |
| + // Scale & convert the entire clip area. |
| + int y_offset = CalculateYOffset(source_rect.left(), source_rect.top(), |
| + last_image_->stride[0]); |
| + int uv_offset = CalculateUVOffset(source_rect.left(), source_rect.top(), |
| + last_image_->stride[1]); |
| + ScaleYUVToRGB32(last_image_->planes[0] + y_offset, |
| + last_image_->planes[1] + uv_offset, |
| + last_image_->planes[2] + uv_offset, |
| + image_buffer, |
| + source_rect.width(), |
| + source_rect.height(), |
| + clip_area.width(), |
| + clip_area.height(), |
| + last_image_->stride[0], |
| + last_image_->stride[1], |
| + image_stride, |
| + media::YV12, |
| + media::ROTATE_0, |
| + media::FILTER_BILINEAR); |
| + |
| + output_region->AddRect(clip_area); |
| + updated_region_.Subtract(source_rect); |
| + return; |
| + } |
| + |
| + 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); |
| + if (rect.is_empty()) |
| + continue; |
| + rect = ScaleRect(rect, screen_size_, view_size); |
| + rect.IntersectWith(clip_area); |
| + if (rect.is_empty()) |
| + continue; |
| + |
| + ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0], |
| + last_image_->planes[1], |
| + last_image_->planes[2], |
| + last_image_->stride[0], |
| + last_image_->stride[1], |
| + screen_size_, |
| + source_clip, |
| + image_buffer, |
| + image_stride, |
| + view_size, |
| + clip_area, |
| + rect); |
| + |
| + output_region->AddRect(rect); |
| + } |
| + |
| + updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_)); |
| + break; |
| + } |
| + default: { |
| + LOG(ERROR) << ": fmt=" << last_image_->fmt; |
|
Sergey Ulanov
2014/05/25 07:13:28
Change this to something line "Unsupported image f
Wez
2014/05/25 22:59:12
Done.
|
| return; |
| - |
| - // Scale & convert the entire clip area. |
| - int y_offset = CalculateYOffset(source_rect.left(), source_rect.top(), |
| - last_image_->stride[0]); |
| - int uv_offset = CalculateUVOffset(source_rect.left(), source_rect.top(), |
| - last_image_->stride[1]); |
| - ScaleYUVToRGB32(last_image_->planes[0] + y_offset, |
| - last_image_->planes[1] + uv_offset, |
| - last_image_->planes[2] + uv_offset, |
| - image_buffer, |
| - source_rect.width(), |
| - source_rect.height(), |
| - clip_area.width(), |
| - clip_area.height(), |
| - last_image_->stride[0], |
| - last_image_->stride[1], |
| - image_stride, |
| - media::YV12, |
| - media::ROTATE_0, |
| - media::FILTER_BILINEAR); |
| - |
| - output_region->AddRect(clip_area); |
| - updated_region_.Subtract(source_rect); |
| - return; |
| - } |
| - |
| - 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); |
| - if (rect.is_empty()) |
| - continue; |
| - rect = ScaleRect(rect, screen_size_, view_size); |
| - rect.IntersectWith(clip_area); |
| - if (rect.is_empty()) |
| - continue; |
| - |
| - ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0], |
| - last_image_->planes[1], |
| - last_image_->planes[2], |
| - last_image_->stride[0], |
| - last_image_->stride[1], |
| - screen_size_, |
| - source_clip, |
| - image_buffer, |
| - image_stride, |
| - view_size, |
| - clip_area, |
| - rect); |
| - |
| - output_region->AddRect(rect); |
| + } |
| } |
| - updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_)); |
| - |
| for (webrtc::DesktopRegion::Iterator i(transparent_region_); |
| !i.IsAtEnd(); i.Advance()) { |
| // Determine the scaled area affected by this rectangle changing. |