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

Side by Side Diff: media/filters/skcanvas_video_renderer.cc

Issue 850993002: gpu video: optimize HW video to SW canvas and implement it for WebRTC. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix android build fail Created 5 years, 10 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 unified diff | Download patch
OLDNEW
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 "gpu/GLES2/gl2extchromium.h" 7 #include "gpu/GLES2/gl2extchromium.h"
8 #include "gpu/command_buffer/client/gles2_interface.h" 8 #include "gpu/command_buffer/client/gles2_interface.h"
9 #include "gpu/command_buffer/common/mailbox_holder.h" 9 #include "gpu/command_buffer/common/mailbox_holder.h"
10 #include "media/base/video_frame.h" 10 #include "media/base/video_frame.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 } 139 }
140 140
141 unsigned texture_id = 141 unsigned texture_id =
142 static_cast<unsigned>((bitmap->getTexture())->getTextureHandle()); 142 static_cast<unsigned>((bitmap->getTexture())->getTextureHandle());
143 // If CopyVideoFrameTextureToGLTexture() changes the state of the 143 // If CopyVideoFrameTextureToGLTexture() changes the state of the
144 // |texture_id|, it's needed to invalidate the state cached in skia, 144 // |texture_id|, it's needed to invalidate the state cached in skia,
145 // but currently the state isn't changed. 145 // but currently the state isn't changed.
146 SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture( 146 SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture(
147 context_3d.gl, video_frame, texture_id, 0, GL_RGBA, GL_UNSIGNED_BYTE, 147 context_3d.gl, video_frame, texture_id, 0, GL_RGBA, GL_UNSIGNED_BYTE,
148 true, false); 148 true, false);
149 bitmap->notifyPixelsChanged();
149 return true; 150 return true;
150 } 151 }
151 152
152 class SyncPointClientImpl : public VideoFrame::SyncPointClient { 153 class SyncPointClientImpl : public VideoFrame::SyncPointClient {
153 public: 154 public:
154 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} 155 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
155 ~SyncPointClientImpl() override {} 156 ~SyncPointClientImpl() override {}
156 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); } 157 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); }
157 void WaitSyncPoint(uint32 sync_point) override { 158 void WaitSyncPoint(uint32 sync_point) override {
158 gl_->WaitSyncPointCHROMIUM(sync_point); 159 gl_->WaitSyncPointCHROMIUM(sync_point);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 // Paint black rectangle if there isn't a frame available or the 315 // Paint black rectangle if there isn't a frame available or the
315 // frame has an unexpected format. 316 // frame has an unexpected format.
316 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || 317 if (!video_frame.get() || video_frame->natural_size().IsEmpty() ||
317 !IsYUVOrNative(video_frame->format())) { 318 !IsYUVOrNative(video_frame->format())) {
318 canvas->drawRect(dest, paint); 319 canvas->drawRect(dest, paint);
319 canvas->flush(); 320 canvas->flush();
320 return; 321 return;
321 } 322 }
322 323
323 SkBitmap* target_frame = nullptr; 324 SkBitmap* target_frame = nullptr;
324 if (canvas->getGrContext()) { 325
326 if (video_frame->format() == VideoFrame::NATIVE_TEXTURE) {
327 // Draw HW Video on both SW and HW Canvas.
328 // In SW Canvas case, rely on skia drawing Ganesh SkBitmap on SW SkCanvas.
325 if (accelerated_last_frame_.isNull() || 329 if (accelerated_last_frame_.isNull() ||
326 video_frame->timestamp() != accelerated_last_frame_timestamp_) { 330 video_frame->timestamp() != accelerated_last_frame_timestamp_) {
327 if (video_frame->format() == VideoFrame::NATIVE_TEXTURE) { 331 DCHECK(context_3d.gl);
328 // Draw HW Video on HW Canvas. 332 DCHECK(context_3d.gr_context);
329 DCHECK(context_3d.gl); 333 if (accelerated_generator_) {
330 DCHECK(context_3d.gr_context); 334 // Reset SkBitmap used in SWVideo-to-HWCanvas path.
331 if (accelerated_generator_) { 335 accelerated_last_frame_.reset();
332 // Reset SkBitmap used in SWVideo-to-HWCanvas path. 336 accelerated_generator_ = nullptr;
333 accelerated_last_frame_.reset(); 337 }
334 accelerated_generator_ = nullptr; 338 if (!CopyVideoFrameTextureToSkBitmapTexture(
335 } 339 video_frame.get(), &accelerated_last_frame_, context_3d)) {
336 if (!CopyVideoFrameTextureToSkBitmapTexture( 340 NOTREACHED();
337 video_frame.get(), &accelerated_last_frame_, context_3d)) { 341 return;
338 NOTREACHED();
339 return;
340 }
341 } else {
342 // Draw SW Video on HW Canvas.
343 if (!accelerated_generator_ && !accelerated_last_frame_.isNull()) {
344 // Reset SkBitmap used in HWVideo-to-HWCanvas path.
345 accelerated_last_frame_.reset();
346 }
347 accelerated_generator_ = new VideoImageGenerator(video_frame);
348
349 // Note: This takes ownership of |accelerated_generator_|.
350 if (!SkInstallDiscardablePixelRef(accelerated_generator_,
351 &accelerated_last_frame_)) {
352 NOTREACHED();
353 return;
354 }
355 } 342 }
356 DCHECK(video_frame->visible_rect().width() == 343 DCHECK(video_frame->visible_rect().width() ==
357 accelerated_last_frame_.width() && 344 accelerated_last_frame_.width() &&
345 video_frame->visible_rect().height() ==
346 accelerated_last_frame_.height());
347
348 accelerated_last_frame_timestamp_ = video_frame->timestamp();
349 }
350 target_frame = &accelerated_last_frame_;
351 accelerated_frame_deleting_timer_.Reset();
352 } else if (canvas->getGrContext()) {
353 DCHECK(video_frame->format() != VideoFrame::NATIVE_TEXTURE);
354 if (accelerated_last_frame_.isNull() ||
355 video_frame->timestamp() != accelerated_last_frame_timestamp_) {
356 // Draw SW Video on HW Canvas.
357 if (!accelerated_generator_ && !accelerated_last_frame_.isNull()) {
358 // Reset SkBitmap used in HWVideo-to-HWCanvas path.
359 accelerated_last_frame_.reset();
360 }
361 accelerated_generator_ = new VideoImageGenerator(video_frame);
362
363 // Note: This takes ownership of |accelerated_generator_|.
364 if (!SkInstallDiscardablePixelRef(accelerated_generator_,
365 &accelerated_last_frame_)) {
366 NOTREACHED();
367 return;
368 }
369 DCHECK(video_frame->visible_rect().width() ==
370 accelerated_last_frame_.width() &&
358 video_frame->visible_rect().height() == 371 video_frame->visible_rect().height() ==
359 accelerated_last_frame_.height()); 372 accelerated_last_frame_.height());
360 373
361 accelerated_last_frame_timestamp_ = video_frame->timestamp(); 374 accelerated_last_frame_timestamp_ = video_frame->timestamp();
362 } else if (accelerated_generator_) { 375 } else if (accelerated_generator_) {
363 accelerated_generator_->set_frame(video_frame); 376 accelerated_generator_->set_frame(video_frame);
364 } 377 }
365 target_frame = &accelerated_last_frame_; 378 target_frame = &accelerated_last_frame_;
366 accelerated_frame_deleting_timer_.Reset(); 379 accelerated_frame_deleting_timer_.Reset();
367 } else { 380 } else {
368 // Draw both SW and HW Video on SW Canvas. 381 // Draw SW Video on SW Canvas.
382 DCHECK(video_frame->format() != VideoFrame::NATIVE_TEXTURE);
369 if (last_frame_.isNull() || 383 if (last_frame_.isNull() ||
370 video_frame->timestamp() != last_frame_timestamp_) { 384 video_frame->timestamp() != last_frame_timestamp_) {
371 // Check if |bitmap| needs to be (re)allocated. 385 // Check if |bitmap| needs to be (re)allocated.
372 if (last_frame_.isNull() || 386 if (last_frame_.isNull() ||
373 last_frame_.width() != video_frame->visible_rect().width() || 387 last_frame_.width() != video_frame->visible_rect().width() ||
374 last_frame_.height() != video_frame->visible_rect().height()) { 388 last_frame_.height() != video_frame->visible_rect().height()) {
375 last_frame_.allocN32Pixels(video_frame->visible_rect().width(), 389 last_frame_.allocN32Pixels(video_frame->visible_rect().width(),
376 video_frame->visible_rect().height()); 390 video_frame->visible_rect().height());
377 last_frame_.setIsVolatile(true); 391 last_frame_.setIsVolatile(true);
378 } 392 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 if (need_transform) 445 if (need_transform)
432 canvas->restore(); 446 canvas->restore();
433 canvas->flush(); 447 canvas->flush();
434 // SkCanvas::flush() causes the generator to generate SkImage, so delete 448 // SkCanvas::flush() causes the generator to generate SkImage, so delete
435 // |video_frame| not to be outlived. 449 // |video_frame| not to be outlived.
436 if (canvas->getGrContext() && accelerated_generator_) 450 if (canvas->getGrContext() && accelerated_generator_)
437 accelerated_generator_->set_frame(nullptr); 451 accelerated_generator_->set_frame(nullptr);
438 } 452 }
439 453
440 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, 454 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
441 SkCanvas* canvas) { 455 SkCanvas* canvas,
456 const Context3D& context_3d) {
442 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff, 457 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff,
443 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, Context3D()); 458 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d);
444 } 459 }
445 460
446 // static 461 // static
447 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( 462 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
448 const scoped_refptr<media::VideoFrame>& video_frame, 463 const scoped_refptr<media::VideoFrame>& video_frame,
449 void* rgb_pixels, 464 void* rgb_pixels,
450 size_t row_bytes) { 465 size_t row_bytes) {
451 DCHECK(IsYUVOrNative(video_frame->format())) 466 DCHECK(IsYUVOrNative(video_frame->format()))
452 << video_frame->format(); 467 << video_frame->format();
453 if (IsYUV(video_frame->format())) { 468 if (IsYUV(video_frame->format())) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 SK_A32_SHIFT == 24 579 SK_A32_SHIFT == 24
565 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels), 580 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels),
566 row_bytes, 581 row_bytes,
567 static_cast<uint8*>(rgb_pixels), 582 static_cast<uint8*>(rgb_pixels),
568 row_bytes, 583 row_bytes,
569 video_frame->visible_rect().width(), 584 video_frame->visible_rect().width(),
570 video_frame->visible_rect().height()); 585 video_frame->visible_rect().height());
571 #endif 586 #endif
572 break; 587 break;
573 588
574 case VideoFrame::NATIVE_TEXTURE: { 589 case VideoFrame::NATIVE_TEXTURE:
575 SkBitmap tmp; 590 NOTREACHED();
576 tmp.installPixels(
577 SkImageInfo::MakeN32Premul(video_frame->visible_rect().width(),
578 video_frame->visible_rect().height()),
579 rgb_pixels,
580 row_bytes);
581 video_frame->ReadPixelsFromNativeTexture(tmp);
582 break; 591 break;
583 }
584
585 #if defined(VIDEO_HOLE) 592 #if defined(VIDEO_HOLE)
586 case VideoFrame::HOLE: 593 case VideoFrame::HOLE:
587 #endif // defined(VIDEO_HOLE) 594 #endif // defined(VIDEO_HOLE)
588 case VideoFrame::ARGB: 595 case VideoFrame::ARGB:
589 case VideoFrame::UNKNOWN: 596 case VideoFrame::UNKNOWN:
590 case VideoFrame::NV12: 597 case VideoFrame::NV12:
591 NOTREACHED(); 598 NOTREACHED();
592 } 599 }
593 } 600 }
594 601
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 last_frame_timestamp_ = media::kNoTimestamp(); 644 last_frame_timestamp_ = media::kNoTimestamp();
638 } 645 }
639 646
640 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() { 647 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() {
641 accelerated_last_frame_.reset(); 648 accelerated_last_frame_.reset();
642 accelerated_generator_ = nullptr; 649 accelerated_generator_ = nullptr;
643 accelerated_last_frame_timestamp_ = media::kNoTimestamp(); 650 accelerated_last_frame_timestamp_ = media::kNoTimestamp();
644 } 651 }
645 652
646 } // namespace media 653 } // namespace media
OLDNEW
« 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