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

Side by Side Diff: media/filters/skcanvas_video_renderer.cc

Issue 619343003: Optimize to copy from rotated video to canvas. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add unittests Created 6 years, 2 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/filters/skcanvas_video_renderer.h" 5 #include "media/filters/skcanvas_video_renderer.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/base/video_frame.h" 8 #include "media/base/video_frame.h"
9 #include "media/base/yuv_convert.h" 9 #include "media/base/yuv_convert.h"
10 #include "third_party/libyuv/include/libyuv.h" 10 #include "third_party/libyuv/include/libyuv.h"
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 320
321 // Check if we should convert and update |last_frame_|. 321 // Check if we should convert and update |last_frame_|.
322 if (last_frame_.isNull() || 322 if (last_frame_.isNull() ||
323 video_frame->timestamp() != last_frame_timestamp_) { 323 video_frame->timestamp() != last_frame_timestamp_) {
324 generator_ = new VideoImageGenerator(video_frame); 324 generator_ = new VideoImageGenerator(video_frame);
325 325
326 // Note: This takes ownership of |generator_|. 326 // Note: This takes ownership of |generator_|.
327 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) { 327 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) {
328 NOTREACHED(); 328 NOTREACHED();
329 } 329 }
330 330 DCHECK(video_frame->visible_rect().width() == last_frame_.width() &&
331 // TODO(rileya): Perform this rotation on the canvas, rather than allocating 331 video_frame->visible_rect().height() == last_frame_.height());
332 // a new bitmap and copying.
333 switch (video_rotation) {
334 case VIDEO_ROTATION_0:
335 break;
336 case VIDEO_ROTATION_90:
337 last_frame_ = SkBitmapOperations::Rotate(
338 last_frame_, SkBitmapOperations::ROTATION_90_CW);
339 break;
340 case VIDEO_ROTATION_180:
341 last_frame_ = SkBitmapOperations::Rotate(
342 last_frame_, SkBitmapOperations::ROTATION_180_CW);
343 break;
344 case VIDEO_ROTATION_270:
345 last_frame_ = SkBitmapOperations::Rotate(
346 last_frame_, SkBitmapOperations::ROTATION_270_CW);
347 break;
348 }
349
350 // We copied the frame into a new bitmap and threw out the old one, so we
351 // no longer have a |generator_| around. This should be removed when the
352 // above TODO is addressed.
353 if (video_rotation != VIDEO_ROTATION_0)
354 generator_ = NULL;
355 332
356 last_frame_timestamp_ = video_frame->timestamp(); 333 last_frame_timestamp_ = video_frame->timestamp();
357 } else if (generator_) { 334 } else if (generator_) {
358 generator_->set_frame(video_frame); 335 generator_->set_frame(video_frame);
359 } 336 }
360 337
361 paint.setXfermodeMode(mode); 338 paint.setXfermodeMode(mode);
339 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
362 340
363 // Paint using |last_frame_|. 341 bool need_transform =
364 paint.setFilterLevel(SkPaint::kLow_FilterLevel); 342 video_rotation != VIDEO_ROTATION_0 ||
365 canvas->drawBitmapRect(last_frame_, NULL, dest, &paint); 343 dest_rect.size() != video_frame->visible_rect().size() ||
344 !dest_rect.origin().IsOrigin();
345 if (need_transform) {
346 canvas->save();
347 canvas->translate(
348 SkFloatToScalar(dest_rect.x() + (dest_rect.width() * 0.5f)),
349 SkFloatToScalar(dest_rect.y() + (dest_rect.height() * 0.5f)));
350 SkScalar angle = SkFloatToScalar(0.0f);
351 switch (video_rotation) {
352 case VIDEO_ROTATION_0:
353 break;
354 case VIDEO_ROTATION_90:
355 angle = SkFloatToScalar(90.0f);
356 break;
357 case VIDEO_ROTATION_180:
358 angle = SkFloatToScalar(180.0f);
359 break;
360 case VIDEO_ROTATION_270:
361 angle = SkFloatToScalar(270.0f);
362 break;
363 }
364 canvas->rotate(angle);
365
366 gfx::SizeF rotated_dest_size = dest_rect.size();
367 if (video_rotation == VIDEO_ROTATION_90 ||
368 video_rotation == VIDEO_ROTATION_270) {
369 rotated_dest_size =
370 gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width());
371 }
372 canvas->scale(
373 SkFloatToScalar(rotated_dest_size.width() / last_frame_.width()),
374 SkFloatToScalar(rotated_dest_size.height() / last_frame_.height()));
375 canvas->translate(-SkFloatToScalar(last_frame_.width() * 0.5f),
376 -SkFloatToScalar(last_frame_.height() * 0.5f));
377 }
378 canvas->drawBitmap(last_frame_, 0, 0, &paint);
379 if (need_transform)
380 canvas->restore();
366 canvas->flush(); 381 canvas->flush();
367 } 382 }
368 383
369 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, 384 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
370 SkCanvas* canvas) { 385 SkCanvas* canvas) {
371 Paint(video_frame, 386 Paint(video_frame,
372 canvas, 387 canvas,
373 video_frame->visible_rect(), 388 video_frame->visible_rect(),
374 0xff, 389 0xff,
375 SkXfermode::kSrc_Mode, 390 SkXfermode::kSrc_Mode,
376 media::VIDEO_ROTATION_0); 391 media::VIDEO_ROTATION_0);
377 } 392 }
378 393
379 } // namespace media 394 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/skcanvas_video_renderer.h ('k') | media/filters/skcanvas_video_renderer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698