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

Side by Side Diff: remoting/base/decoder_vp8.cc

Issue 8954003: Revised sub-rectangle scaling for use in Chromoting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Replace bounds-check on loop with a DCHECK. Created 9 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/base/decoder_vp8.h" 5 #include "remoting/base/decoder_vp8.h"
6 6
7 #include <math.h>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "media/base/media.h" 10 #include "media/base/media.h"
9 #include "media/base/yuv_convert.h" 11 #include "media/base/yuv_convert.h"
10 #include "remoting/base/util.h" 12 #include "remoting/base/util.h"
11 13
12 extern "C" { 14 extern "C" {
13 #define VPX_CODEC_DISABLE_COMPAT 1 15 #define VPX_CODEC_DISABLE_COMPAT 1
14 #include "third_party/libvpx/libvpx.h" 16 #include "third_party/libvpx/libvpx.h"
15 } 17 }
16 18
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 if (!DoScaling()) 149 if (!DoScaling())
148 ConvertRects(rects, &updated_rects_); 150 ConvertRects(rects, &updated_rects_);
149 else 151 else
150 ScaleAndConvertRects(rects, &updated_rects_); 152 ScaleAndConvertRects(rects, &updated_rects_);
151 } 153 }
152 154
153 bool DecoderVp8::DoScaling() const { 155 bool DecoderVp8::DoScaling() const {
154 return horizontal_scale_ratio_ != 1.0 || vertical_scale_ratio_ != 1.0; 156 return horizontal_scale_ratio_ != 1.0 || vertical_scale_ratio_ != 1.0;
155 } 157 }
156 158
157 void DecoderVp8::ConvertRects(const RectVector& rects, 159 void DecoderVp8::ConvertRects(const RectVector& input_rects,
158 RectVector* output_rects) { 160 RectVector* output_rects) {
159 if (!last_image_) 161 if (!last_image_)
160 return; 162 return;
161 163
162 uint8* data_start = frame_->data(media::VideoFrame::kRGBPlane); 164 // The conversion routine we use is optimized for even widths & heights.
163 const int stride = frame_->stride(media::VideoFrame::kRGBPlane); 165 int image_width = RoundToTwosMultiple(last_image_->d_w);
166 int image_height = RoundToTwosMultiple(last_image_->d_h);
167
168 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
169 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
164 170
165 output_rects->clear(); 171 output_rects->clear();
166 output_rects->reserve(rects.size()); 172
167 for (size_t i = 0; i < rects.size(); ++i) { 173 // Clip based on both the output dimensions and Pepper clip rect.
168 // Clip by the clipping rectangle first. 174 SkIRect clip_rect = clip_rect_;
169 SkIRect dest_rect = rects[i]; 175 if (!clip_rect.intersect(SkIRect::MakeWH(image_width, image_height)))
170 if (!dest_rect.intersect(clip_rect_)) 176 return;
177
178 output_rects->reserve(input_rects.size());
179
180 for (size_t i = 0; i < input_rects.size(); ++i) {
181 // Align the rectangle to avoid artifacts in color space conversion.
182 SkIRect dest_rect = AlignRect(input_rects[i]);
183
184 // Clip to the image and Pepper clip region.
185 if (!dest_rect.intersect(clip_rect))
171 continue; 186 continue;
172 187
173 // Round down the image width and height.
174 int image_width = RoundToTwosMultiple(last_image_->d_w);
175 int image_height = RoundToTwosMultiple(last_image_->d_h);
176
177 // Then clip by the rounded down dimension of the image for safety.
178 if (!dest_rect.intersect(SkIRect::MakeWH(image_width, image_height)))
179 continue;
180
181 // Align the rectangle to avoid artifacts in color space conversion.
182 dest_rect = AlignRect(dest_rect);
183
184 ConvertYUVToRGB32WithRect(last_image_->planes[0], 188 ConvertYUVToRGB32WithRect(last_image_->planes[0],
185 last_image_->planes[1], 189 last_image_->planes[1],
186 last_image_->planes[2], 190 last_image_->planes[2],
187 data_start, 191 output_rgb_buf,
188 dest_rect, 192 dest_rect,
189 last_image_->stride[0], 193 last_image_->stride[0],
190 last_image_->stride[1], 194 last_image_->stride[1],
191 stride); 195 output_stride);
196
192 output_rects->push_back(dest_rect); 197 output_rects->push_back(dest_rect);
193 } 198 }
194 } 199 }
195 200
196 void DecoderVp8::ScaleAndConvertRects(const RectVector& rects, 201 void DecoderVp8::ScaleAndConvertRects(const RectVector& input_rects,
197 RectVector* output_rects) { 202 RectVector* output_rects) {
198 if (!last_image_) 203 if (!last_image_)
199 return; 204 return;
200 205
201 uint8* data_start = frame_->data(media::VideoFrame::kRGBPlane); 206 int input_width = last_image_->d_w;
202 const int stride = frame_->stride(media::VideoFrame::kRGBPlane); 207 int input_height = last_image_->d_h;
208
209 uint8* output_rgb_buf = frame_->data(media::VideoFrame::kRGBPlane);
210 const int output_stride = frame_->stride(media::VideoFrame::kRGBPlane);
211
212 // TODO(wez): Resize |frame_| to our desired output dimensions when scaling.
213 int output_width = ceil(input_width * horizontal_scale_ratio_);
214 int output_height = ceil(input_height * vertical_scale_ratio_);
203 215
204 output_rects->clear(); 216 output_rects->clear();
205 output_rects->reserve(rects.size());
206 for (size_t i = 0; i < rects.size(); ++i) {
207 // Round down the image width and height.
208 int image_width = RoundToTwosMultiple(last_image_->d_w);
209 int image_height = RoundToTwosMultiple(last_image_->d_h);
210 217
211 // Clip by the rounded down dimension of the image for safety. 218 // Clip based on both the output dimensions and Pepper clip rect.
212 SkIRect dest_rect = rects[i]; 219 SkIRect clip_rect = clip_rect_;
213 if (!dest_rect.intersect(SkIRect::MakeWH(image_width, image_height))) 220 if (!clip_rect.intersect(SkIRect::MakeWH(output_width, output_height)))
221 return;
222
223 output_rects->reserve(input_rects.size());
224
225 for (size_t i = 0; i < input_rects.size(); ++i) {
226 // Determine the scaled area affected by this rectangle changing.
227 SkIRect output_rect = ScaleRect(input_rects[i],
228 horizontal_scale_ratio_,
229 vertical_scale_ratio_);
230 if (!output_rect.intersect(clip_rect))
214 continue; 231 continue;
215 232
216 // Align the rectangle to avoid artifacts in color space conversion. 233 // The scaler will not to read outside the input dimensions.
217 dest_rect = AlignRect(dest_rect); 234 media::ScaleYUVToRGB32WithRect(last_image_->planes[0],
218 235 last_image_->planes[1],
219 SkIRect scaled_rect = ScaleRect(dest_rect, 236 last_image_->planes[2],
220 horizontal_scale_ratio_, 237 output_rgb_buf,
221 vertical_scale_ratio_); 238 input_width,
222 239 input_height,
223 ScaleYUVToRGB32WithRect(last_image_->planes[0], 240 output_width, output_height,
224 last_image_->planes[1], 241 output_rect.x(),
225 last_image_->planes[2], 242 output_rect.y(),
226 data_start, 243 output_rect.right(),
227 dest_rect, 244 output_rect.bottom(),
228 scaled_rect, 245 last_image_->stride[0],
229 last_image_->stride[0], 246 last_image_->stride[1],
230 last_image_->stride[1], 247 output_stride);
231 stride); 248 output_rects->push_back(output_rect);
232 output_rects->push_back(scaled_rect);
233 } 249 }
234 } 250 }
235 251
236 } // namespace remoting 252 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698