| Index: media/filters/skcanvas_video_renderer.cc
|
| diff --git a/media/filters/skcanvas_video_renderer.cc b/media/filters/skcanvas_video_renderer.cc
|
| index dc95dc6596fdf1ac1b04424e90b9ee0954c1342c..9bdd393e56c31c368b926de08be9e4e42a993382 100644
|
| --- a/media/filters/skcanvas_video_renderer.cc
|
| +++ b/media/filters/skcanvas_video_renderer.cc
|
| @@ -29,12 +29,45 @@
|
| namespace media {
|
|
|
| static bool IsYUV(media::VideoFrame::Format format) {
|
| - return format == media::VideoFrame::YV12 ||
|
| - format == media::VideoFrame::YV16 ||
|
| - format == media::VideoFrame::I420 ||
|
| - format == media::VideoFrame::YV12A ||
|
| - format == media::VideoFrame::YV12J ||
|
| - format == media::VideoFrame::YV24;
|
| + switch (format) {
|
| + case VideoFrame::YV12:
|
| + case VideoFrame::YV16:
|
| + case VideoFrame::I420:
|
| + case VideoFrame::YV12A:
|
| + case VideoFrame::YV12J:
|
| + case VideoFrame::YV24:
|
| + case VideoFrame::NV12:
|
| + return true;
|
| + case VideoFrame::UNKNOWN:
|
| + case VideoFrame::NATIVE_TEXTURE:
|
| +#if defined(VIDEO_HOLE)
|
| + case VideoFrame::HOLE:
|
| +#endif // defined(VIDEO_HOLE)
|
| + return false;
|
| + }
|
| + NOTREACHED() << "Invalid videoframe format provided: " << format;
|
| + return false;
|
| +}
|
| +
|
| +static bool IsJPEGColorSpace(media::VideoFrame::Format format) {
|
| + switch (format) {
|
| + case VideoFrame::YV12J:
|
| + return true;
|
| + case VideoFrame::YV12:
|
| + case VideoFrame::YV16:
|
| + case VideoFrame::I420:
|
| + case VideoFrame::YV12A:
|
| + case VideoFrame::YV24:
|
| + case VideoFrame::NV12:
|
| + case VideoFrame::UNKNOWN:
|
| + case VideoFrame::NATIVE_TEXTURE:
|
| +#if defined(VIDEO_HOLE)
|
| + case VideoFrame::HOLE:
|
| +#endif // defined(VIDEO_HOLE)
|
| + return false;
|
| + }
|
| + NOTREACHED() << "Invalid videoframe format provided: " << format;
|
| + return false;
|
| }
|
|
|
| static bool IsYUVOrNative(media::VideoFrame::Format format) {
|
| @@ -178,6 +211,8 @@ class VideoImageGenerator : public SkImageGenerator {
|
| VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) {}
|
| virtual ~VideoImageGenerator() {}
|
|
|
| + void set_frame(const scoped_refptr<VideoFrame>& frame) { frame_ = frame; }
|
| +
|
| protected:
|
| virtual bool onGetInfo(SkImageInfo* info) OVERRIDE {
|
| info->fWidth = frame_->visible_rect().width();
|
| @@ -204,42 +239,56 @@ class VideoImageGenerator : public SkImageGenerator {
|
|
|
| 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)
|
| + size_t row_bytes[3],
|
| + SkYUVColorSpace* color_space) OVERRIDE {
|
| + if (!frame_.get() || !IsYUV(frame_->format()))
|
| return false;
|
| +
|
| + if (color_space) {
|
| + if (IsJPEGColorSpace(frame_->format()))
|
| + *color_space = kJPEG_SkYUVColorSpace;
|
| + else
|
| + *color_space = kRec601_SkYUVColorSpace;
|
| + }
|
| +
|
| for (int plane = VideoFrame::kYPlane; plane <= VideoFrame::kVPlane;
|
| ++plane) {
|
| if (sizes) {
|
| gfx::Size size;
|
| - size = VideoFrame::PlaneSize(
|
| - frame_->format(), plane, frame_->coded_size());
|
| + size =
|
| + VideoFrame::PlaneSize(frame_->format(),
|
| + plane,
|
| + gfx::Size(frame_->visible_rect().width(),
|
| + frame_->visible_rect().height()));
|
| sizes[plane].set(size.width(), size.height());
|
| }
|
| - if (row_bytes)
|
| - row_bytes[plane] = frame_->stride(plane);
|
| - if (planes)
|
| - planes[plane] = frame_->data(plane);
|
| + if (row_bytes && planes) {
|
| + size_t offset;
|
| + int y_shift = (frame_->format() == media::VideoFrame::YV16) ? 0 : 1;
|
| + if (plane == media::VideoFrame::kYPlane) {
|
| + offset = (frame_->stride(media::VideoFrame::kYPlane) *
|
| + frame_->visible_rect().y()) +
|
| + frame_->visible_rect().x();
|
| + } else {
|
| + offset = (frame_->stride(media::VideoFrame::kUPlane) *
|
| + (frame_->visible_rect().y() >> y_shift)) +
|
| + (frame_->visible_rect().x() >> 1);
|
| + }
|
| + row_bytes[plane] = static_cast<size_t>(frame_->stride(plane));
|
| + planes[plane] = frame_->data(plane) + offset;
|
| + }
|
| }
|
| 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()
|
| - : generator_(NULL),
|
| - last_frame_timestamp_(media::kNoTimestamp()) {
|
| + : generator_(NULL), last_frame_timestamp_(media::kNoTimestamp()) {
|
| last_frame_.setIsVolatile(true);
|
| }
|
|
|
| @@ -265,6 +314,7 @@ void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame,
|
| // frame has an unexpected format.
|
| if (!video_frame.get() || !IsYUVOrNative(video_frame->format())) {
|
| canvas->drawRect(dest, paint);
|
| + canvas->flush();
|
| return;
|
| }
|
|
|
| @@ -297,8 +347,14 @@ void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame,
|
| break;
|
| }
|
|
|
| + // We copied the frame into a new bitmap and threw out the old one, so we
|
| + // no longer have a |generator_| around. This should be removed when the
|
| + // above TODO is addressed.
|
| + if (video_rotation != VIDEO_ROTATION_0)
|
| + generator_ = NULL;
|
| +
|
| last_frame_timestamp_ = video_frame->timestamp();
|
| - } else {
|
| + } else if (generator_) {
|
| generator_->set_frame(video_frame);
|
| }
|
|
|
| @@ -307,6 +363,7 @@ void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame,
|
| // Paint using |last_frame_|.
|
| paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
| canvas->drawBitmapRect(last_frame_, NULL, dest, &paint);
|
| + canvas->flush();
|
| }
|
|
|
| void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
|
|
|