| Index: media/filters/skcanvas_video_renderer.cc
|
| diff --git a/media/filters/skcanvas_video_renderer.cc b/media/filters/skcanvas_video_renderer.cc
|
| index 003c1951a9b4010e93e612a347d645b22aa3f66a..ead8d066516ac0065759807b46755c9b146bee8a 100644
|
| --- a/media/filters/skcanvas_video_renderer.cc
|
| +++ b/media/filters/skcanvas_video_renderer.cc
|
| @@ -9,8 +9,12 @@
|
| #include "media/base/yuv_convert.h"
|
| #include "third_party/libyuv/include/libyuv.h"
|
| #include "third_party/skia/include/core/SkCanvas.h"
|
| +#include "third_party/skia/include/gpu/SkGr.h"
|
| +#include "third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.h"
|
| #include "ui/gfx/skbitmap_operations.h"
|
|
|
| +#include "skia/ext/refptr.h"
|
| +
|
| // Skia internal format depends on a platform. On Android it is ABGR, on others
|
| // it is ARGB.
|
| #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \
|
| @@ -209,6 +213,61 @@ void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
|
| return;
|
| }
|
|
|
| + // If we have an accelerated canvas, then we can use Ganesh's YUV conversion
|
| + // filter, this is far faster than carrying this out on the CPU.
|
| + if (GrContext* gr = canvas->getGrContext()) {
|
| + DCHECK(IsYUVOrNative(video_frame->format()))
|
| + << video_frame->format();
|
| + if (IsYUV(video_frame->format())) {
|
| + DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane),
|
| + video_frame->stride(media::VideoFrame::kVPlane));
|
| + }
|
| +
|
| + DCHECK(video_frame->format() == VideoFrame::YV12);
|
| +
|
| +
|
| + // Wrap our planes in SkBitmaps.
|
| + SkBitmap bmps[3];
|
| + bmps[0].installPixels(
|
| + SkImageInfo::MakeA8(video_frame->coded_size().width(),
|
| + video_frame->coded_size().height()),
|
| + video_frame->data(VideoFrame::kYPlane),
|
| + video_frame->row_bytes(VideoFrame::kYPlane));
|
| + bmps[1].installPixels(
|
| + SkImageInfo::MakeA8(video_frame->coded_size().width() / 2,
|
| + video_frame->coded_size().height() / 2),
|
| + video_frame->data(VideoFrame::kUPlane),
|
| + video_frame->row_bytes(VideoFrame::kUPlane));
|
| + bmps[2].installPixels(
|
| + SkImageInfo::MakeA8(video_frame->coded_size().width() / 2,
|
| + video_frame->coded_size().height() / 2),
|
| + video_frame->data(VideoFrame::kVPlane),
|
| + video_frame->row_bytes(VideoFrame::kVPlane));
|
| +
|
| + for (int i = 0; i < 3; ++i)
|
| + bmps[i].setIsVolatile(true);
|
| +
|
| + GrTexture* planes[3];
|
| +
|
| + planes[0] = GrLockAndRefCachedBitmapTexture(gr, bmps[0], NULL);
|
| + planes[1] = GrLockAndRefCachedBitmapTexture(gr, bmps[1], NULL);
|
| + planes[2] = GrLockAndRefCachedBitmapTexture(gr, bmps[2], NULL);
|
| +
|
| + skia::RefPtr<GrEffect> effect = skia::AdoptRef<GrEffect>(
|
| + GrYUVtoRGBEffect::Create(planes[0], planes[1], planes[2]));
|
| +
|
| + if (effect) {
|
| + GrPaint gp;
|
| + gp.addColorEffect(effect.get());
|
| + gr->drawPaint(gp);
|
| + }
|
| +
|
| + GrUnlockAndUnrefCachedBitmapTexture(planes[0]);
|
| + GrUnlockAndUnrefCachedBitmapTexture(planes[1]);
|
| + GrUnlockAndUnrefCachedBitmapTexture(planes[2]);
|
| + return;
|
| + }
|
| +
|
| // Check if we should convert and update |last_frame_|.
|
| if (last_frame_.isNull() ||
|
| video_frame->timestamp() != last_frame_timestamp_) {
|
|
|