| 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" |
| 11 #include "third_party/skia/include/core/SkCanvas.h" | 11 #include "third_party/skia/include/core/SkCanvas.h" |
| 12 #include "third_party/skia/include/core/SkImageGenerator.h" |
| 12 #include "ui/gfx/skbitmap_operations.h" | 13 #include "ui/gfx/skbitmap_operations.h" |
| 13 | 14 |
| 14 // Skia internal format depends on a platform. On Android it is ABGR, on others | 15 // Skia internal format depends on a platform. On Android it is ABGR, on others |
| 15 // it is ARGB. | 16 // it is ARGB. |
| 16 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ | 17 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ |
| 17 SK_A32_SHIFT == 24 | 18 SK_A32_SHIFT == 24 |
| 18 #define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB | 19 #define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB |
| 19 #define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB | 20 #define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB |
| 20 #elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \ | 21 #elif SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \ |
| 21 SK_A32_SHIFT == 24 | 22 SK_A32_SHIFT == 24 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 33 format == media::VideoFrame::I420 || | 34 format == media::VideoFrame::I420 || |
| 34 format == media::VideoFrame::YV12A || | 35 format == media::VideoFrame::YV12A || |
| 35 format == media::VideoFrame::YV12J || | 36 format == media::VideoFrame::YV12J || |
| 36 format == media::VideoFrame::YV24; | 37 format == media::VideoFrame::YV24; |
| 37 } | 38 } |
| 38 | 39 |
| 39 static bool IsYUVOrNative(media::VideoFrame::Format format) { | 40 static bool IsYUVOrNative(media::VideoFrame::Format format) { |
| 40 return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE; | 41 return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE; |
| 41 } | 42 } |
| 42 | 43 |
| 43 // Converts a VideoFrame containing YUV data to a SkBitmap containing RGB data. | 44 // Converts a |video_frame| to raw |rgb_pixels|. |
| 44 // | 45 static void ConvertVideoFrameToRGBPixels( |
| 45 // |bitmap| will be (re)allocated to match the dimensions of |video_frame|. | |
| 46 static void ConvertVideoFrameToBitmap( | |
| 47 const scoped_refptr<media::VideoFrame>& video_frame, | 46 const scoped_refptr<media::VideoFrame>& video_frame, |
| 48 SkBitmap* bitmap) { | 47 void* rgb_pixels, |
| 48 size_t row_bytes) { |
| 49 DCHECK(IsYUVOrNative(video_frame->format())) | 49 DCHECK(IsYUVOrNative(video_frame->format())) |
| 50 << video_frame->format(); | 50 << video_frame->format(); |
| 51 if (IsYUV(video_frame->format())) { | 51 if (IsYUV(video_frame->format())) { |
| 52 DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane), | 52 DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane), |
| 53 video_frame->stride(media::VideoFrame::kVPlane)); | 53 video_frame->stride(media::VideoFrame::kVPlane)); |
| 54 } | 54 } |
| 55 | 55 |
| 56 // Check if |bitmap| needs to be (re)allocated. | |
| 57 if (bitmap->isNull() || | |
| 58 bitmap->width() != video_frame->visible_rect().width() || | |
| 59 bitmap->height() != video_frame->visible_rect().height()) { | |
| 60 bitmap->allocN32Pixels(video_frame->visible_rect().width(), | |
| 61 video_frame->visible_rect().height()); | |
| 62 bitmap->setIsVolatile(true); | |
| 63 } | |
| 64 | |
| 65 bitmap->lockPixels(); | |
| 66 | |
| 67 size_t y_offset = 0; | 56 size_t y_offset = 0; |
| 68 size_t uv_offset = 0; | 57 size_t uv_offset = 0; |
| 69 if (IsYUV(video_frame->format())) { | 58 if (IsYUV(video_frame->format())) { |
| 70 int y_shift = (video_frame->format() == media::VideoFrame::YV16) ? 0 : 1; | 59 int y_shift = (video_frame->format() == media::VideoFrame::YV16) ? 0 : 1; |
| 71 // Use the "left" and "top" of the destination rect to locate the offset | 60 // Use the "left" and "top" of the destination rect to locate the offset |
| 72 // in Y, U and V planes. | 61 // in Y, U and V planes. |
| 73 y_offset = (video_frame->stride(media::VideoFrame::kYPlane) * | 62 y_offset = (video_frame->stride(media::VideoFrame::kYPlane) * |
| 74 video_frame->visible_rect().y()) + | 63 video_frame->visible_rect().y()) + |
| 75 video_frame->visible_rect().x(); | 64 video_frame->visible_rect().x(); |
| 76 // For format YV12, there is one U, V value per 2x2 block. | 65 // For format YV12, there is one U, V value per 2x2 block. |
| 77 // For format YV16, there is one U, V value per 2x1 block. | 66 // For format YV16, there is one U, V value per 2x1 block. |
| 78 uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) * | 67 uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) * |
| 79 (video_frame->visible_rect().y() >> y_shift)) + | 68 (video_frame->visible_rect().y() >> y_shift)) + |
| 80 (video_frame->visible_rect().x() >> 1); | 69 (video_frame->visible_rect().x() >> 1); |
| 81 } | 70 } |
| 82 | 71 |
| 83 switch (video_frame->format()) { | 72 switch (video_frame->format()) { |
| 84 case media::VideoFrame::YV12: | 73 case media::VideoFrame::YV12: |
| 85 case media::VideoFrame::I420: | 74 case media::VideoFrame::I420: |
| 86 LIBYUV_I420_TO_ARGB( | 75 LIBYUV_I420_TO_ARGB( |
| 87 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 76 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 88 video_frame->stride(media::VideoFrame::kYPlane), | 77 video_frame->stride(media::VideoFrame::kYPlane), |
| 89 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 78 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 90 video_frame->stride(media::VideoFrame::kUPlane), | 79 video_frame->stride(media::VideoFrame::kUPlane), |
| 91 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 80 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 92 video_frame->stride(media::VideoFrame::kVPlane), | 81 video_frame->stride(media::VideoFrame::kVPlane), |
| 93 static_cast<uint8*>(bitmap->getPixels()), | 82 static_cast<uint8*>(rgb_pixels), |
| 94 bitmap->rowBytes(), | 83 row_bytes, |
| 95 video_frame->visible_rect().width(), | 84 video_frame->visible_rect().width(), |
| 96 video_frame->visible_rect().height()); | 85 video_frame->visible_rect().height()); |
| 97 break; | 86 break; |
| 98 | 87 |
| 99 case media::VideoFrame::YV12J: | 88 case media::VideoFrame::YV12J: |
| 100 media::ConvertYUVToRGB32( | 89 media::ConvertYUVToRGB32( |
| 101 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 90 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 102 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 91 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 103 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 92 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 104 static_cast<uint8*>(bitmap->getPixels()), | 93 static_cast<uint8*>(rgb_pixels), |
| 105 video_frame->visible_rect().width(), | 94 video_frame->visible_rect().width(), |
| 106 video_frame->visible_rect().height(), | 95 video_frame->visible_rect().height(), |
| 107 video_frame->stride(media::VideoFrame::kYPlane), | 96 video_frame->stride(media::VideoFrame::kYPlane), |
| 108 video_frame->stride(media::VideoFrame::kUPlane), | 97 video_frame->stride(media::VideoFrame::kUPlane), |
| 109 bitmap->rowBytes(), | 98 row_bytes, |
| 110 media::YV12J); | 99 media::YV12J); |
| 111 break; | 100 break; |
| 112 | 101 |
| 113 case media::VideoFrame::YV16: | 102 case media::VideoFrame::YV16: |
| 114 LIBYUV_I422_TO_ARGB( | 103 LIBYUV_I422_TO_ARGB( |
| 115 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 104 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 116 video_frame->stride(media::VideoFrame::kYPlane), | 105 video_frame->stride(media::VideoFrame::kYPlane), |
| 117 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 106 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 118 video_frame->stride(media::VideoFrame::kUPlane), | 107 video_frame->stride(media::VideoFrame::kUPlane), |
| 119 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 108 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 120 video_frame->stride(media::VideoFrame::kVPlane), | 109 video_frame->stride(media::VideoFrame::kVPlane), |
| 121 static_cast<uint8*>(bitmap->getPixels()), | 110 static_cast<uint8*>(rgb_pixels), |
| 122 bitmap->rowBytes(), | 111 row_bytes, |
| 123 video_frame->visible_rect().width(), | 112 video_frame->visible_rect().width(), |
| 124 video_frame->visible_rect().height()); | 113 video_frame->visible_rect().height()); |
| 125 break; | 114 break; |
| 126 | 115 |
| 127 case media::VideoFrame::YV12A: | 116 case media::VideoFrame::YV12A: |
| 128 // Since libyuv doesn't support YUVA, fallback to media, which is not ARM | 117 // Since libyuv doesn't support YUVA, fallback to media, which is not ARM |
| 129 // optimized. | 118 // optimized. |
| 130 // TODO(fbarchard, mtomasz): Use libyuv, then copy the alpha channel. | 119 // TODO(fbarchard, mtomasz): Use libyuv, then copy the alpha channel. |
| 131 media::ConvertYUVAToARGB( | 120 media::ConvertYUVAToARGB( |
| 132 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 121 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 133 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 122 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 134 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 123 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 135 video_frame->data(media::VideoFrame::kAPlane), | 124 video_frame->data(media::VideoFrame::kAPlane), |
| 136 static_cast<uint8*>(bitmap->getPixels()), | 125 static_cast<uint8*>(rgb_pixels), |
| 137 video_frame->visible_rect().width(), | 126 video_frame->visible_rect().width(), |
| 138 video_frame->visible_rect().height(), | 127 video_frame->visible_rect().height(), |
| 139 video_frame->stride(media::VideoFrame::kYPlane), | 128 video_frame->stride(media::VideoFrame::kYPlane), |
| 140 video_frame->stride(media::VideoFrame::kUPlane), | 129 video_frame->stride(media::VideoFrame::kUPlane), |
| 141 video_frame->stride(media::VideoFrame::kAPlane), | 130 video_frame->stride(media::VideoFrame::kAPlane), |
| 142 bitmap->rowBytes(), | 131 row_bytes, |
| 143 media::YV12); | 132 media::YV12); |
| 144 break; | 133 break; |
| 145 | 134 |
| 146 case media::VideoFrame::YV24: | 135 case media::VideoFrame::YV24: |
| 147 libyuv::I444ToARGB( | 136 libyuv::I444ToARGB( |
| 148 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 137 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 149 video_frame->stride(media::VideoFrame::kYPlane), | 138 video_frame->stride(media::VideoFrame::kYPlane), |
| 150 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 139 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 151 video_frame->stride(media::VideoFrame::kUPlane), | 140 video_frame->stride(media::VideoFrame::kUPlane), |
| 152 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 141 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 153 video_frame->stride(media::VideoFrame::kVPlane), | 142 video_frame->stride(media::VideoFrame::kVPlane), |
| 154 static_cast<uint8*>(bitmap->getPixels()), | 143 static_cast<uint8*>(rgb_pixels), |
| 155 bitmap->rowBytes(), | 144 row_bytes, |
| 156 video_frame->visible_rect().width(), | 145 video_frame->visible_rect().width(), |
| 157 video_frame->visible_rect().height()); | 146 video_frame->visible_rect().height()); |
| 158 #if SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \ | 147 #if SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \ |
| 159 SK_A32_SHIFT == 24 | 148 SK_A32_SHIFT == 24 |
| 160 libyuv::ARGBToABGR( | 149 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels), |
| 161 static_cast<uint8*>(bitmap->getPixels()), | 150 row_bytes, |
| 162 bitmap->rowBytes(), | 151 static_cast<uint8*>(rgb_pixels), |
| 163 static_cast<uint8*>(bitmap->getPixels()), | 152 row_bytes, |
| 164 bitmap->rowBytes(), | 153 video_frame->visible_rect().width(), |
| 165 video_frame->visible_rect().width(), | 154 video_frame->visible_rect().height()); |
| 166 video_frame->visible_rect().height()); | |
| 167 #endif | 155 #endif |
| 168 break; | 156 break; |
| 169 | 157 |
| 170 case media::VideoFrame::NATIVE_TEXTURE: | 158 case media::VideoFrame::NATIVE_TEXTURE: { |
| 171 DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE); | 159 DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE); |
| 172 video_frame->ReadPixelsFromNativeTexture(*bitmap); | 160 SkBitmap tmp; |
| 161 tmp.installPixels( |
| 162 SkImageInfo::MakeN32Premul(video_frame->visible_rect().width(), |
| 163 video_frame->visible_rect().height()), |
| 164 rgb_pixels, |
| 165 row_bytes); |
| 166 video_frame->ReadPixelsFromNativeTexture(tmp); |
| 173 break; | 167 break; |
| 174 | 168 } |
| 175 default: | 169 default: |
| 176 NOTREACHED(); | 170 NOTREACHED(); |
| 177 break; | 171 break; |
| 178 } | 172 } |
| 179 bitmap->notifyPixelsChanged(); | |
| 180 bitmap->unlockPixels(); | |
| 181 } | 173 } |
| 182 | 174 |
| 175 // Generates an RGB image from a VideoFrame. |
| 176 class VideoImageGenerator : public SkImageGenerator { |
| 177 public: |
| 178 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) {} |
| 179 virtual ~VideoImageGenerator() {} |
| 180 |
| 181 protected: |
| 182 virtual bool onGetInfo(SkImageInfo* info) OVERRIDE { |
| 183 info->fWidth = frame_->visible_rect().width(); |
| 184 info->fHeight = frame_->visible_rect().height(); |
| 185 info->fColorType = kN32_SkColorType; |
| 186 info->fAlphaType = kPremul_SkAlphaType; |
| 187 return true; |
| 188 } |
| 189 |
| 190 virtual bool onGetPixels(const SkImageInfo& info, |
| 191 void* pixels, |
| 192 size_t row_bytes, |
| 193 SkPMColor ctable[], |
| 194 int* ctable_count) OVERRIDE { |
| 195 if (!frame_.get()) |
| 196 return false; |
| 197 if (!pixels) |
| 198 return true; |
| 199 // If skia couldn't do the YUV conversion, we will. |
| 200 ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes); |
| 201 frame_ = NULL; |
| 202 return true; |
| 203 } |
| 204 |
| 205 virtual bool onGetYUV8Planes(SkISize sizes[3], |
| 206 void* planes[3], |
| 207 size_t row_bytes[3]) OVERRIDE { |
| 208 if (!frame_.get()) |
| 209 return false; |
| 210 // Currently Skia only supports JPEG color range YUV. |
| 211 if (frame_->format() != VideoFrame::YV12J) |
| 212 return false; |
| 213 for (int plane = VideoFrame::kYPlane; plane <= VideoFrame::kVPlane; |
| 214 ++plane) { |
| 215 if (sizes) { |
| 216 gfx::Size size; |
| 217 size = VideoFrame::PlaneSize( |
| 218 frame_->format(), plane, frame_->coded_size()); |
| 219 sizes[plane].set(size.width(), size.height()); |
| 220 } |
| 221 if (row_bytes) |
| 222 row_bytes[plane] = frame_->stride(plane); |
| 223 if (planes) |
| 224 planes[plane] = frame_->data(plane); |
| 225 } |
| 226 if (planes && row_bytes) |
| 227 frame_ = NULL; |
| 228 return true; |
| 229 } |
| 230 public: |
| 231 |
| 232 virtual void set_frame(const scoped_refptr<VideoFrame>& frame) { |
| 233 frame_ = frame; |
| 234 } |
| 235 |
| 236 private: |
| 237 scoped_refptr<VideoFrame> frame_; |
| 238 }; |
| 239 |
| 183 SkCanvasVideoRenderer::SkCanvasVideoRenderer() | 240 SkCanvasVideoRenderer::SkCanvasVideoRenderer() |
| 184 : last_frame_timestamp_(media::kNoTimestamp()) { | 241 : generator_(NULL), |
| 242 last_frame_timestamp_(media::kNoTimestamp()) { |
| 243 last_frame_.setIsVolatile(true); |
| 185 } | 244 } |
| 186 | 245 |
| 187 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {} | 246 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {} |
| 188 | 247 |
| 189 void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame, | 248 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, |
| 190 SkCanvas* canvas, | 249 SkCanvas* canvas, |
| 191 const gfx::RectF& dest_rect, | 250 const gfx::RectF& dest_rect, |
| 192 uint8 alpha, | 251 uint8 alpha, |
| 193 SkXfermode::Mode mode, | 252 SkXfermode::Mode mode, |
| 194 VideoRotation video_rotation) { | 253 VideoRotation video_rotation) { |
| 195 if (alpha == 0) { | 254 if (alpha == 0) { |
| 196 return; | 255 return; |
| 197 } | 256 } |
| 198 | 257 |
| 199 SkRect dest; | 258 SkRect dest; |
| 200 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); | 259 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); |
| 201 | 260 |
| 202 SkPaint paint; | 261 SkPaint paint; |
| 203 paint.setAlpha(alpha); | 262 paint.setAlpha(alpha); |
| 204 | 263 |
| 205 // Paint black rectangle if there isn't a frame available or the | 264 // Paint black rectangle if there isn't a frame available or the |
| 206 // frame has an unexpected format. | 265 // frame has an unexpected format. |
| 207 if (!video_frame || !IsYUVOrNative(video_frame->format())) { | 266 if (!video_frame.get() || !IsYUVOrNative(video_frame->format())) { |
| 208 canvas->drawRect(dest, paint); | 267 canvas->drawRect(dest, paint); |
| 209 return; | 268 return; |
| 210 } | 269 } |
| 211 | 270 |
| 212 // Check if we should convert and update |last_frame_|. | 271 // Check if we should convert and update |last_frame_|. |
| 213 if (last_frame_.isNull() || | 272 if (last_frame_.isNull() || |
| 214 video_frame->timestamp() != last_frame_timestamp_) { | 273 video_frame->timestamp() != last_frame_timestamp_) { |
| 215 ConvertVideoFrameToBitmap(video_frame, &last_frame_); | 274 generator_ = new VideoImageGenerator(video_frame); |
| 216 | 275 |
| 276 // Note: This takes ownership of |generator_|. |
| 277 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) { |
| 278 NOTREACHED(); |
| 279 } |
| 280 |
| 281 // TODO(rileya): Perform this rotation on the canvas, rather than allocating |
| 282 // a new bitmap and copying. |
| 217 switch (video_rotation) { | 283 switch (video_rotation) { |
| 218 case VIDEO_ROTATION_0: | 284 case VIDEO_ROTATION_0: |
| 219 break; | 285 break; |
| 220 case VIDEO_ROTATION_90: | 286 case VIDEO_ROTATION_90: |
| 221 last_frame_ = SkBitmapOperations::Rotate( | 287 last_frame_ = SkBitmapOperations::Rotate( |
| 222 last_frame_, SkBitmapOperations::ROTATION_90_CW); | 288 last_frame_, SkBitmapOperations::ROTATION_90_CW); |
| 223 break; | 289 break; |
| 224 case VIDEO_ROTATION_180: | 290 case VIDEO_ROTATION_180: |
| 225 last_frame_ = SkBitmapOperations::Rotate( | 291 last_frame_ = SkBitmapOperations::Rotate( |
| 226 last_frame_, SkBitmapOperations::ROTATION_180_CW); | 292 last_frame_, SkBitmapOperations::ROTATION_180_CW); |
| 227 break; | 293 break; |
| 228 case VIDEO_ROTATION_270: | 294 case VIDEO_ROTATION_270: |
| 229 last_frame_ = SkBitmapOperations::Rotate( | 295 last_frame_ = SkBitmapOperations::Rotate( |
| 230 last_frame_, SkBitmapOperations::ROTATION_270_CW); | 296 last_frame_, SkBitmapOperations::ROTATION_270_CW); |
| 231 break; | 297 break; |
| 232 } | 298 } |
| 233 | 299 |
| 234 last_frame_timestamp_ = video_frame->timestamp(); | 300 last_frame_timestamp_ = video_frame->timestamp(); |
| 301 } else { |
| 302 generator_->set_frame(video_frame); |
| 235 } | 303 } |
| 236 | 304 |
| 237 paint.setXfermodeMode(mode); | 305 paint.setXfermodeMode(mode); |
| 238 | 306 |
| 239 // Paint using |last_frame_|. | 307 // Paint using |last_frame_|. |
| 240 paint.setFilterLevel(SkPaint::kLow_FilterLevel); | 308 paint.setFilterLevel(SkPaint::kLow_FilterLevel); |
| 241 canvas->drawBitmapRect(last_frame_, NULL, dest, &paint); | 309 canvas->drawBitmapRect(last_frame_, NULL, dest, &paint); |
| 242 } | 310 } |
| 243 | 311 |
| 244 void SkCanvasVideoRenderer::Copy(media::VideoFrame* video_frame, | 312 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 245 SkCanvas* canvas) { | 313 SkCanvas* canvas) { |
| 246 Paint(video_frame, | 314 Paint(video_frame, |
| 247 canvas, | 315 canvas, |
| 248 video_frame->visible_rect(), | 316 video_frame->visible_rect(), |
| 249 0xff, | 317 0xff, |
| 250 SkXfermode::kSrc_Mode, | 318 SkXfermode::kSrc_Mode, |
| 251 media::VIDEO_ROTATION_0); | 319 media::VIDEO_ROTATION_0); |
| 252 } | 320 } |
| 253 | 321 |
| 254 } // namespace media | 322 } // namespace media |
| OLD | NEW |