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

Side by Side 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: 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/codec/video_decoder_vpx.h" 5 #include "remoting/codec/video_decoder_vpx.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "media/base/media.h" 12 #include "media/base/media.h"
13 #include "media/base/yuv_convert.h" 13 #include "media/base/yuv_convert.h"
14 #include "remoting/base/util.h" 14 #include "remoting/base/util.h"
15 #include "third_party/libyuv/include/libyuv/convert_argb.h"
15 16
16 extern "C" { 17 extern "C" {
17 #define VPX_CODEC_DISABLE_COMPAT 1 18 #define VPX_CODEC_DISABLE_COMPAT 1
18 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h" 19 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h"
19 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" 20 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
20 } 21 }
21 22
22 namespace remoting { 23 namespace remoting {
23 24
24 namespace { 25 namespace {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 DCHECK(!screen_size_.is_empty()); 171 DCHECK(!screen_size_.is_empty());
171 DCHECK(!view_size.is_empty()); 172 DCHECK(!view_size.is_empty());
172 173
173 // Early-return and do nothing if we haven't yet decoded any frames. 174 // Early-return and do nothing if we haven't yet decoded any frames.
174 if (!last_image_) 175 if (!last_image_)
175 return; 176 return;
176 177
177 webrtc::DesktopRect source_clip = 178 webrtc::DesktopRect source_clip =
178 webrtc::DesktopRect::MakeWH(last_image_->d_w, last_image_->d_h); 179 webrtc::DesktopRect::MakeWH(last_image_->d_w, last_image_->d_h);
179 180
180 // ScaleYUVToRGB32WithRect does not currently support up-scaling. We won't 181 // VP8 only outputs I420 frames, but VP9 can also produce I444.
181 // be asked to up-scale except during resizes or if page zoom is >100%, so 182 switch (last_image_->fmt) {
182 // we work-around the limitation by using the slower ScaleYUVToRGB32. 183 case VPX_IMG_FMT_I444: {
183 // TODO(wez): Remove this hack if/when ScaleYUVToRGB32WithRect can up-scale. 184 // TODO(wez): Add scaling support to the I444 conversion path.
184 if (!updated_region_.is_empty() && 185 if (view_size.equals(screen_size_)) {
185 (source_clip.width() < view_size.width() || 186 for (webrtc::DesktopRegion::Iterator i(updated_region_);
186 source_clip.height() < view_size.height())) { 187 !i.IsAtEnd(); i.Advance()) {
187 // We're scaling only |clip_area| into the |image_buffer|, so we need to 188 // Determine the scaled area affected by this rectangle changing.
188 // work out which source rectangle that corresponds to. 189 webrtc::DesktopRect rect = i.rect();
189 webrtc::DesktopRect source_rect = 190 rect.IntersectWith(source_clip);
190 ScaleRect(clip_area, view_size, screen_size_); 191 rect.IntersectWith(clip_area);
191 source_rect = webrtc::DesktopRect::MakeLTRB( 192 if (rect.is_empty())
192 RoundToTwosMultiple(source_rect.left()), 193 continue;
193 RoundToTwosMultiple(source_rect.top()),
194 source_rect.right(),
195 source_rect.bottom());
196 194
197 // If there were no changes within the clip source area then don't render. 195 int image_offset = image_stride * rect.top() +
198 webrtc::DesktopRegion intersection(source_rect); 196 rect.left() * VideoDecoder::kBytesPerPixel;
199 intersection.IntersectWith(updated_region_); 197 int y_offset = last_image_->stride[0] * rect.top() + rect.left();
200 if (intersection.is_empty()) 198 int u_offset = last_image_->stride[1] * rect.top() + rect.left();
199 int v_offset = last_image_->stride[2] * rect.top() + rect.left();
200 libyuv::I444ToARGB(last_image_->planes[0] + y_offset,
201 last_image_->stride[0],
202 last_image_->planes[1] + u_offset,
203 last_image_->stride[1],
204 last_image_->planes[2] + v_offset,
205 last_image_->stride[2],
206 image_buffer + image_offset, image_stride,
207 rect.width(), rect.height());
208
209 output_region->AddRect(rect);
210 }
211 }
212 break;
213 }
214 case VPX_IMG_FMT_I420: {
215 // ScaleYUVToRGB32WithRect does not currently support up-scaling. We
216 // won't be asked to up-scale except during resizes or if page zoom is
217 // >100%, so we work-around the limitation by using the slower
218 // ScaleYUVToRGB32.
219 // TODO(wez): Remove this hack if/when ScaleYUVToRGB32WithRect can
220 // up-scale.
221 if (!updated_region_.is_empty() &&
222 (source_clip.width() < view_size.width() ||
223 source_clip.height() < view_size.height())) {
224 // We're scaling only |clip_area| into the |image_buffer|, so we need to
225 // work out which source rectangle that corresponds to.
226 webrtc::DesktopRect source_rect =
227 ScaleRect(clip_area, view_size, screen_size_);
228 source_rect = webrtc::DesktopRect::MakeLTRB(
229 RoundToTwosMultiple(source_rect.left()),
230 RoundToTwosMultiple(source_rect.top()),
231 source_rect.right(),
232 source_rect.bottom());
233
234 // If there were no changes within the clip source area then don't
235 // render.
236 webrtc::DesktopRegion intersection(source_rect);
237 intersection.IntersectWith(updated_region_);
238 if (intersection.is_empty())
239 return;
240
241 // Scale & convert the entire clip area.
242 int y_offset = CalculateYOffset(source_rect.left(), source_rect.top(),
243 last_image_->stride[0]);
244 int uv_offset = CalculateUVOffset(source_rect.left(), source_rect.top(),
245 last_image_->stride[1]);
246 ScaleYUVToRGB32(last_image_->planes[0] + y_offset,
247 last_image_->planes[1] + uv_offset,
248 last_image_->planes[2] + uv_offset,
249 image_buffer,
250 source_rect.width(),
251 source_rect.height(),
252 clip_area.width(),
253 clip_area.height(),
254 last_image_->stride[0],
255 last_image_->stride[1],
256 image_stride,
257 media::YV12,
258 media::ROTATE_0,
259 media::FILTER_BILINEAR);
260
261 output_region->AddRect(clip_area);
262 updated_region_.Subtract(source_rect);
263 return;
264 }
265
266 for (webrtc::DesktopRegion::Iterator i(updated_region_);
267 !i.IsAtEnd(); i.Advance()) {
268 // Determine the scaled area affected by this rectangle changing.
269 webrtc::DesktopRect rect = i.rect();
270 rect.IntersectWith(source_clip);
271 if (rect.is_empty())
272 continue;
273 rect = ScaleRect(rect, screen_size_, view_size);
274 rect.IntersectWith(clip_area);
275 if (rect.is_empty())
276 continue;
277
278 ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0],
279 last_image_->planes[1],
280 last_image_->planes[2],
281 last_image_->stride[0],
282 last_image_->stride[1],
283 screen_size_,
284 source_clip,
285 image_buffer,
286 image_stride,
287 view_size,
288 clip_area,
289 rect);
290
291 output_region->AddRect(rect);
292 }
293
294 updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_));
295 break;
296 }
297 default: {
298 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.
201 return; 299 return;
202 300 }
203 // Scale & convert the entire clip area.
204 int y_offset = CalculateYOffset(source_rect.left(), source_rect.top(),
205 last_image_->stride[0]);
206 int uv_offset = CalculateUVOffset(source_rect.left(), source_rect.top(),
207 last_image_->stride[1]);
208 ScaleYUVToRGB32(last_image_->planes[0] + y_offset,
209 last_image_->planes[1] + uv_offset,
210 last_image_->planes[2] + uv_offset,
211 image_buffer,
212 source_rect.width(),
213 source_rect.height(),
214 clip_area.width(),
215 clip_area.height(),
216 last_image_->stride[0],
217 last_image_->stride[1],
218 image_stride,
219 media::YV12,
220 media::ROTATE_0,
221 media::FILTER_BILINEAR);
222
223 output_region->AddRect(clip_area);
224 updated_region_.Subtract(source_rect);
225 return;
226 } 301 }
227 302
228 for (webrtc::DesktopRegion::Iterator i(updated_region_);
229 !i.IsAtEnd(); i.Advance()) {
230 // Determine the scaled area affected by this rectangle changing.
231 webrtc::DesktopRect rect = i.rect();
232 rect.IntersectWith(source_clip);
233 if (rect.is_empty())
234 continue;
235 rect = ScaleRect(rect, screen_size_, view_size);
236 rect.IntersectWith(clip_area);
237 if (rect.is_empty())
238 continue;
239
240 ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0],
241 last_image_->planes[1],
242 last_image_->planes[2],
243 last_image_->stride[0],
244 last_image_->stride[1],
245 screen_size_,
246 source_clip,
247 image_buffer,
248 image_stride,
249 view_size,
250 clip_area,
251 rect);
252
253 output_region->AddRect(rect);
254 }
255
256 updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_));
257
258 for (webrtc::DesktopRegion::Iterator i(transparent_region_); 303 for (webrtc::DesktopRegion::Iterator i(transparent_region_);
259 !i.IsAtEnd(); i.Advance()) { 304 !i.IsAtEnd(); i.Advance()) {
260 // Determine the scaled area affected by this rectangle changing. 305 // Determine the scaled area affected by this rectangle changing.
261 webrtc::DesktopRect rect = i.rect(); 306 webrtc::DesktopRect rect = i.rect();
262 rect.IntersectWith(source_clip); 307 rect.IntersectWith(source_clip);
263 if (rect.is_empty()) 308 if (rect.is_empty())
264 continue; 309 continue;
265 rect = ScaleRect(rect, screen_size_, view_size); 310 rect = ScaleRect(rect, screen_size_, view_size);
266 rect.IntersectWith(clip_area); 311 rect.IntersectWith(clip_area);
267 if (rect.is_empty()) 312 if (rect.is_empty())
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 webrtc::DesktopRegion difference = *new_desktop_shape; 346 webrtc::DesktopRegion difference = *new_desktop_shape;
302 difference.Subtract(desktop_shape_); 347 difference.Subtract(desktop_shape_);
303 updated_region_.AddRegion(difference); 348 updated_region_.AddRegion(difference);
304 updated_region_.IntersectWith(*new_desktop_shape); 349 updated_region_.IntersectWith(*new_desktop_shape);
305 350
306 // Set the new desktop shape region. 351 // Set the new desktop shape region.
307 desktop_shape_.Swap(new_desktop_shape); 352 desktop_shape_.Swap(new_desktop_shape);
308 } 353 }
309 354
310 } // namespace remoting 355 } // namespace remoting
OLDNEW
« 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