OLD | NEW |
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 Loading... |
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 |
OLD | NEW |