Chromium Code Reviews| 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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 } | 201 } |
| 202 default: | 202 default: |
| 203 NOTREACHED(); | 203 NOTREACHED(); |
| 204 break; | 204 break; |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 // Generates an RGB image from a VideoFrame. | 208 // Generates an RGB image from a VideoFrame. |
| 209 class VideoImageGenerator : public SkImageGenerator { | 209 class VideoImageGenerator : public SkImageGenerator { |
| 210 public: | 210 public: |
| 211 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) {} | 211 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) { |
| 212 DCHECK(frame_.get()); | |
| 213 } | |
| 212 virtual ~VideoImageGenerator() {} | 214 virtual ~VideoImageGenerator() {} |
| 213 | 215 |
| 214 void set_frame(const scoped_refptr<VideoFrame>& frame) { frame_ = frame; } | 216 void set_frame(const scoped_refptr<VideoFrame>& frame) { frame_ = frame; } |
| 215 | 217 |
| 216 protected: | 218 protected: |
| 217 virtual bool onGetInfo(SkImageInfo* info) override { | 219 virtual bool onGetInfo(SkImageInfo* info) override { |
| 218 info->fWidth = frame_->visible_rect().width(); | 220 info->fWidth = frame_->visible_rect().width(); |
| 219 info->fHeight = frame_->visible_rect().height(); | 221 info->fHeight = frame_->visible_rect().height(); |
| 220 info->fColorType = kN32_SkColorType; | 222 info->fColorType = kN32_SkColorType; |
| 221 info->fAlphaType = kPremul_SkAlphaType; | 223 info->fAlphaType = kPremul_SkAlphaType; |
| 222 return true; | 224 return true; |
| 223 } | 225 } |
| 224 | 226 |
| 225 virtual bool onGetPixels(const SkImageInfo& info, | 227 virtual bool onGetPixels(const SkImageInfo& info, |
| 226 void* pixels, | 228 void* pixels, |
| 227 size_t row_bytes, | 229 size_t row_bytes, |
| 228 SkPMColor ctable[], | 230 SkPMColor ctable[], |
| 229 int* ctable_count) override { | 231 int* ctable_count) override { |
| 230 if (!frame_.get()) | 232 if (!frame_.get()) |
| 231 return false; | 233 return false; |
| 232 if (!pixels) | 234 if (!pixels) |
| 233 return true; | 235 return false; |
| 234 // If skia couldn't do the YUV conversion, we will. | 236 // If skia couldn't do the YUV conversion, we will. |
| 235 ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes); | 237 ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes); |
| 236 frame_ = NULL; | |
| 237 return true; | 238 return true; |
| 238 } | 239 } |
| 239 | 240 |
| 240 virtual bool onGetYUV8Planes(SkISize sizes[3], | 241 virtual bool onGetYUV8Planes(SkISize sizes[3], |
| 241 void* planes[3], | 242 void* planes[3], |
| 242 size_t row_bytes[3], | 243 size_t row_bytes[3], |
| 243 SkYUVColorSpace* color_space) override { | 244 SkYUVColorSpace* color_space) override { |
| 244 if (!frame_.get() || !IsYUV(frame_->format())) | 245 if (!frame_.get() || !IsYUV(frame_->format())) |
| 245 return false; | 246 return false; |
| 246 | 247 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 271 frame_->visible_rect().x(); | 272 frame_->visible_rect().x(); |
| 272 } else { | 273 } else { |
| 273 offset = (frame_->stride(media::VideoFrame::kUPlane) * | 274 offset = (frame_->stride(media::VideoFrame::kUPlane) * |
| 274 (frame_->visible_rect().y() >> y_shift)) + | 275 (frame_->visible_rect().y() >> y_shift)) + |
| 275 (frame_->visible_rect().x() >> 1); | 276 (frame_->visible_rect().x() >> 1); |
| 276 } | 277 } |
| 277 row_bytes[plane] = static_cast<size_t>(frame_->stride(plane)); | 278 row_bytes[plane] = static_cast<size_t>(frame_->stride(plane)); |
| 278 planes[plane] = frame_->data(plane) + offset; | 279 planes[plane] = frame_->data(plane) + offset; |
| 279 } | 280 } |
| 280 } | 281 } |
| 281 if (planes && row_bytes) | |
| 282 frame_ = NULL; | |
| 283 return true; | 282 return true; |
| 284 } | 283 } |
| 285 | 284 |
| 286 private: | 285 private: |
| 287 scoped_refptr<VideoFrame> frame_; | 286 scoped_refptr<VideoFrame> frame_; |
| 287 | |
| 288 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator); | |
| 288 }; | 289 }; |
| 289 | 290 |
| 290 SkCanvasVideoRenderer::SkCanvasVideoRenderer() | 291 SkCanvasVideoRenderer::SkCanvasVideoRenderer() |
| 291 : generator_(NULL), last_frame_timestamp_(media::kNoTimestamp()) { | 292 : generator_(NULL), last_frame_timestamp_(media::kNoTimestamp()) { |
| 292 last_frame_.setIsVolatile(true); | 293 last_frame_.setIsVolatile(true); |
| 293 } | 294 } |
| 294 | 295 |
| 295 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {} | 296 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {} |
| 296 | 297 |
| 297 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, | 298 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 325 | 326 |
| 326 // Note: This takes ownership of |generator_|. | 327 // Note: This takes ownership of |generator_|. |
| 327 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) { | 328 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) { |
| 328 NOTREACHED(); | 329 NOTREACHED(); |
| 329 } | 330 } |
| 330 DCHECK(video_frame->visible_rect().width() == last_frame_.width() && | 331 DCHECK(video_frame->visible_rect().width() == last_frame_.width() && |
| 331 video_frame->visible_rect().height() == last_frame_.height()); | 332 video_frame->visible_rect().height() == last_frame_.height()); |
| 332 | 333 |
| 333 last_frame_timestamp_ = video_frame->timestamp(); | 334 last_frame_timestamp_ = video_frame->timestamp(); |
| 334 } else if (generator_) { | 335 } else if (generator_) { |
| 335 generator_->set_frame(video_frame); | 336 generator_->set_frame(video_frame); |
|
dshwang
2014/10/10 16:50:20
This line is needed because |generator_| generates
| |
| 336 } | 337 } |
| 337 | 338 |
| 338 paint.setXfermodeMode(mode); | 339 paint.setXfermodeMode(mode); |
| 339 paint.setFilterLevel(SkPaint::kLow_FilterLevel); | 340 paint.setFilterLevel(SkPaint::kLow_FilterLevel); |
| 340 | 341 |
| 341 bool need_transform = | 342 bool need_transform = |
| 342 video_rotation != VIDEO_ROTATION_0 || | 343 video_rotation != VIDEO_ROTATION_0 || |
| 343 dest_rect.size() != video_frame->visible_rect().size() || | 344 dest_rect.size() != video_frame->visible_rect().size() || |
| 344 !dest_rect.origin().IsOrigin(); | 345 !dest_rect.origin().IsOrigin(); |
| 345 if (need_transform) { | 346 if (need_transform) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 372 canvas->scale( | 373 canvas->scale( |
| 373 SkFloatToScalar(rotated_dest_size.width() / last_frame_.width()), | 374 SkFloatToScalar(rotated_dest_size.width() / last_frame_.width()), |
| 374 SkFloatToScalar(rotated_dest_size.height() / last_frame_.height())); | 375 SkFloatToScalar(rotated_dest_size.height() / last_frame_.height())); |
| 375 canvas->translate(-SkFloatToScalar(last_frame_.width() * 0.5f), | 376 canvas->translate(-SkFloatToScalar(last_frame_.width() * 0.5f), |
| 376 -SkFloatToScalar(last_frame_.height() * 0.5f)); | 377 -SkFloatToScalar(last_frame_.height() * 0.5f)); |
| 377 } | 378 } |
| 378 canvas->drawBitmap(last_frame_, 0, 0, &paint); | 379 canvas->drawBitmap(last_frame_, 0, 0, &paint); |
| 379 if (need_transform) | 380 if (need_transform) |
| 380 canvas->restore(); | 381 canvas->restore(); |
| 381 canvas->flush(); | 382 canvas->flush(); |
| 383 // SkCanvas::flush() causes the generator to generate SkImage, so delete | |
| 384 // |video_frame| not to be outlived. | |
| 385 if (generator_) | |
| 386 generator_->set_frame(NULL); | |
| 382 } | 387 } |
| 383 | 388 |
| 384 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, | 389 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 385 SkCanvas* canvas) { | 390 SkCanvas* canvas) { |
| 386 Paint(video_frame, | 391 Paint(video_frame, |
| 387 canvas, | 392 canvas, |
| 388 video_frame->visible_rect(), | 393 video_frame->visible_rect(), |
| 389 0xff, | 394 0xff, |
| 390 SkXfermode::kSrc_Mode, | 395 SkXfermode::kSrc_Mode, |
| 391 media::VIDEO_ROTATION_0); | 396 media::VIDEO_ROTATION_0); |
| 392 } | 397 } |
| 393 | 398 |
| 394 } // namespace media | 399 } // namespace media |
| OLD | NEW |