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 |