Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(703)

Unified Diff: remoting/codec/video_decoder_vpx.cc

Issue 300653002: Add support for I444 frames to VideoDecoderVpx. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comment Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..0be92018a618fd927b0818c3e1b53fd3c9ab36d5 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) << "Unsupported image format:" << last_image_->fmt;
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.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698