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

Unified Diff: media/filters/skcanvas_video_renderer.cc

Issue 531353002: Add VideoImageGenerator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..dc95dc6596fdf1ac1b04424e90b9ee0954c1342c 100644
--- a/media/filters/skcanvas_video_renderer.cc
+++ b/media/filters/skcanvas_video_renderer.cc
@@ -9,6 +9,7 @@
#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/core/SkImageGenerator.h"
#include "ui/gfx/skbitmap_operations.h"
// Skia internal format depends on a platform. On Android it is ABGR, on others
@@ -40,12 +41,11 @@ static bool IsYUVOrNative(media::VideoFrame::Format format) {
return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE;
}
-// Converts a VideoFrame containing YUV data to a SkBitmap containing RGB data.
-//
-// |bitmap| will be (re)allocated to match the dimensions of |video_frame|.
-static void ConvertVideoFrameToBitmap(
+// Converts a |video_frame| to raw |rgb_pixels|.
+static void ConvertVideoFrameToRGBPixels(
const scoped_refptr<media::VideoFrame>& video_frame,
- SkBitmap* bitmap) {
+ void* rgb_pixels,
+ size_t row_bytes) {
DCHECK(IsYUVOrNative(video_frame->format()))
<< video_frame->format();
if (IsYUV(video_frame->format())) {
@@ -53,17 +53,6 @@ static void ConvertVideoFrameToBitmap(
video_frame->stride(media::VideoFrame::kVPlane));
}
- // Check if |bitmap| needs to be (re)allocated.
- if (bitmap->isNull() ||
- bitmap->width() != video_frame->visible_rect().width() ||
- bitmap->height() != video_frame->visible_rect().height()) {
- bitmap->allocN32Pixels(video_frame->visible_rect().width(),
- video_frame->visible_rect().height());
- bitmap->setIsVolatile(true);
- }
-
- bitmap->lockPixels();
-
size_t y_offset = 0;
size_t uv_offset = 0;
if (IsYUV(video_frame->format())) {
@@ -90,8 +79,8 @@ static void ConvertVideoFrameToBitmap(
video_frame->stride(media::VideoFrame::kUPlane),
video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
video_frame->stride(media::VideoFrame::kVPlane),
- static_cast<uint8*>(bitmap->getPixels()),
- bitmap->rowBytes(),
+ static_cast<uint8*>(rgb_pixels),
+ row_bytes,
video_frame->visible_rect().width(),
video_frame->visible_rect().height());
break;
@@ -101,12 +90,12 @@ static void ConvertVideoFrameToBitmap(
video_frame->data(media::VideoFrame::kYPlane) + y_offset,
video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
- static_cast<uint8*>(bitmap->getPixels()),
+ static_cast<uint8*>(rgb_pixels),
video_frame->visible_rect().width(),
video_frame->visible_rect().height(),
video_frame->stride(media::VideoFrame::kYPlane),
video_frame->stride(media::VideoFrame::kUPlane),
- bitmap->rowBytes(),
+ row_bytes,
media::YV12J);
break;
@@ -118,8 +107,8 @@ static void ConvertVideoFrameToBitmap(
video_frame->stride(media::VideoFrame::kUPlane),
video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
video_frame->stride(media::VideoFrame::kVPlane),
- static_cast<uint8*>(bitmap->getPixels()),
- bitmap->rowBytes(),
+ static_cast<uint8*>(rgb_pixels),
+ row_bytes,
video_frame->visible_rect().width(),
video_frame->visible_rect().height());
break;
@@ -133,13 +122,13 @@ static void ConvertVideoFrameToBitmap(
video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
video_frame->data(media::VideoFrame::kAPlane),
- static_cast<uint8*>(bitmap->getPixels()),
+ static_cast<uint8*>(rgb_pixels),
video_frame->visible_rect().width(),
video_frame->visible_rect().height(),
video_frame->stride(media::VideoFrame::kYPlane),
video_frame->stride(media::VideoFrame::kUPlane),
video_frame->stride(media::VideoFrame::kAPlane),
- bitmap->rowBytes(),
+ row_bytes,
media::YV12);
break;
@@ -151,42 +140,112 @@ static void ConvertVideoFrameToBitmap(
video_frame->stride(media::VideoFrame::kUPlane),
video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
video_frame->stride(media::VideoFrame::kVPlane),
- static_cast<uint8*>(bitmap->getPixels()),
- bitmap->rowBytes(),
+ static_cast<uint8*>(rgb_pixels),
+ row_bytes,
video_frame->visible_rect().width(),
video_frame->visible_rect().height());
#if SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
SK_A32_SHIFT == 24
- libyuv::ARGBToABGR(
- static_cast<uint8*>(bitmap->getPixels()),
- bitmap->rowBytes(),
- static_cast<uint8*>(bitmap->getPixels()),
- bitmap->rowBytes(),
- video_frame->visible_rect().width(),
- video_frame->visible_rect().height());
+ libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels),
+ row_bytes,
+ static_cast<uint8*>(rgb_pixels),
+ row_bytes,
+ video_frame->visible_rect().width(),
+ video_frame->visible_rect().height());
#endif
break;
- case media::VideoFrame::NATIVE_TEXTURE:
+ case media::VideoFrame::NATIVE_TEXTURE: {
DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE);
- video_frame->ReadPixelsFromNativeTexture(*bitmap);
+ SkBitmap tmp;
+ tmp.installPixels(
+ SkImageInfo::MakeN32Premul(video_frame->visible_rect().width(),
+ video_frame->visible_rect().height()),
+ rgb_pixels,
+ row_bytes);
+ video_frame->ReadPixelsFromNativeTexture(tmp);
break;
-
+ }
default:
NOTREACHED();
break;
}
- bitmap->notifyPixelsChanged();
- bitmap->unlockPixels();
}
+// Generates an RGB image from a VideoFrame.
+class VideoImageGenerator : public SkImageGenerator {
+ public:
+ VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) {}
+ virtual ~VideoImageGenerator() {}
+
+ protected:
+ virtual bool onGetInfo(SkImageInfo* info) OVERRIDE {
+ info->fWidth = frame_->visible_rect().width();
+ info->fHeight = frame_->visible_rect().height();
+ info->fColorType = kN32_SkColorType;
+ info->fAlphaType = kPremul_SkAlphaType;
+ return true;
+ }
+
+ virtual bool onGetPixels(const SkImageInfo& info,
+ void* pixels,
+ size_t row_bytes,
+ SkPMColor ctable[],
+ int* ctable_count) OVERRIDE {
+ if (!frame_.get())
+ return false;
+ if (!pixels)
+ return true;
+ // If skia couldn't do the YUV conversion, we will.
+ ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes);
+ frame_ = NULL;
+ return true;
+ }
+
+ virtual bool onGetYUV8Planes(SkISize sizes[3],
+ void* planes[3],
+ size_t row_bytes[3]) OVERRIDE {
+ if (!frame_.get())
+ return false;
+ // Currently Skia only supports JPEG color range YUV.
+ if (frame_->format() != VideoFrame::YV12J)
+ return false;
+ for (int plane = VideoFrame::kYPlane; plane <= VideoFrame::kVPlane;
+ ++plane) {
+ if (sizes) {
+ gfx::Size size;
+ size = VideoFrame::PlaneSize(
+ frame_->format(), plane, frame_->coded_size());
+ sizes[plane].set(size.width(), size.height());
+ }
+ if (row_bytes)
+ row_bytes[plane] = frame_->stride(plane);
+ if (planes)
+ planes[plane] = frame_->data(plane);
+ }
+ if (planes && row_bytes)
+ frame_ = NULL;
+ return true;
+ }
+ public:
+
+ virtual void set_frame(const scoped_refptr<VideoFrame>& frame) {
+ frame_ = frame;
+ }
+
+ private:
+ scoped_refptr<VideoFrame> frame_;
+};
+
SkCanvasVideoRenderer::SkCanvasVideoRenderer()
- : last_frame_timestamp_(media::kNoTimestamp()) {
+ : generator_(NULL),
+ last_frame_timestamp_(media::kNoTimestamp()) {
+ last_frame_.setIsVolatile(true);
}
SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {}
-void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
+void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame,
SkCanvas* canvas,
const gfx::RectF& dest_rect,
uint8 alpha,
@@ -204,7 +263,7 @@ void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
// Paint black rectangle if there isn't a frame available or the
// frame has an unexpected format.
- if (!video_frame || !IsYUVOrNative(video_frame->format())) {
+ if (!video_frame.get() || !IsYUVOrNative(video_frame->format())) {
canvas->drawRect(dest, paint);
return;
}
@@ -212,8 +271,15 @@ void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
// Check if we should convert and update |last_frame_|.
if (last_frame_.isNull() ||
video_frame->timestamp() != last_frame_timestamp_) {
- ConvertVideoFrameToBitmap(video_frame, &last_frame_);
+ generator_ = new VideoImageGenerator(video_frame);
+
+ // Note: This takes ownership of |generator_|.
+ if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) {
+ NOTREACHED();
+ }
+ // TODO(rileya): Perform this rotation on the canvas, rather than allocating
+ // a new bitmap and copying.
switch (video_rotation) {
case VIDEO_ROTATION_0:
break;
@@ -232,6 +298,8 @@ void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
}
last_frame_timestamp_ = video_frame->timestamp();
+ } else {
+ generator_->set_frame(video_frame);
}
paint.setXfermodeMode(mode);
@@ -241,7 +309,7 @@ void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
canvas->drawBitmapRect(last_frame_, NULL, dest, &paint);
}
-void SkCanvasVideoRenderer::Copy(media::VideoFrame* video_frame,
+void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
SkCanvas* canvas) {
Paint(video_frame,
canvas,
« 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