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

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: Created 5 years, 11 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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 SK_A32_SHIFT == 24 196 SK_A32_SHIFT == 24
197 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels), 197 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels),
198 row_bytes, 198 row_bytes,
199 static_cast<uint8*>(rgb_pixels), 199 static_cast<uint8*>(rgb_pixels),
200 row_bytes, 200 row_bytes,
201 video_frame->visible_rect().width(), 201 video_frame->visible_rect().width(),
202 video_frame->visible_rect().height()); 202 video_frame->visible_rect().height());
203 #endif 203 #endif
204 break; 204 break;
205 205
206 case media::VideoFrame::NATIVE_TEXTURE: { 206 case media::VideoFrame::NATIVE_TEXTURE:
207 SkBitmap tmp; 207 NOTREACHED();
208 tmp.installPixels(
209 SkImageInfo::MakeN32Premul(video_frame->visible_rect().width(),
210 video_frame->visible_rect().height()),
211 rgb_pixels,
212 row_bytes);
213 video_frame->ReadPixelsFromNativeTexture(tmp);
dshwang 2015/01/14 20:32:13 Remove this complicated ReadPixel callback impleme
214 break; 208 break;
215 }
216
217 case media::VideoFrame::ARGB: 209 case media::VideoFrame::ARGB:
218 default: 210 default:
219 NOTREACHED(); 211 NOTREACHED();
220 break; 212 break;
221 } 213 }
222 } 214 }
223 215
224 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap, 216 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap,
225 const gfx::Size& size) { 217 const gfx::Size& size) {
226 return bitmap->getTexture() && bitmap->width() == size.width() && 218 return bitmap->getTexture() && bitmap->width() == size.width() &&
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 261 }
270 262
271 unsigned texture_id = 263 unsigned texture_id =
272 static_cast<unsigned>((bitmap->getTexture())->getTextureHandle()); 264 static_cast<unsigned>((bitmap->getTexture())->getTextureHandle());
273 // If CopyVideoFrameTextureToGLTexture() changes the state of the 265 // If CopyVideoFrameTextureToGLTexture() changes the state of the
274 // |texture_id|, it's needed to invalidate the state cached in skia, 266 // |texture_id|, it's needed to invalidate the state cached in skia,
275 // but currently the state isn't changed. 267 // but currently the state isn't changed.
276 SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture( 268 SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture(
277 context_3d.gl, video_frame, texture_id, 0, GL_RGBA, GL_UNSIGNED_BYTE, 269 context_3d.gl, video_frame, texture_id, 0, GL_RGBA, GL_UNSIGNED_BYTE,
278 true, false); 270 true, false);
271 bitmap->notifyPixelsChanged();
279 return true; 272 return true;
280 } 273 }
281 274
282 class SyncPointClientImpl : public VideoFrame::SyncPointClient { 275 class SyncPointClientImpl : public VideoFrame::SyncPointClient {
283 public: 276 public:
284 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} 277 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
285 ~SyncPointClientImpl() override {} 278 ~SyncPointClientImpl() override {}
286 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); } 279 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); }
287 void WaitSyncPoint(uint32 sync_point) override { 280 void WaitSyncPoint(uint32 sync_point) override {
288 gl_->WaitSyncPointCHROMIUM(sync_point); 281 gl_->WaitSyncPointCHROMIUM(sync_point);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 // Paint black rectangle if there isn't a frame available or the 411 // Paint black rectangle if there isn't a frame available or the
419 // frame has an unexpected format. 412 // frame has an unexpected format.
420 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || 413 if (!video_frame.get() || video_frame->natural_size().IsEmpty() ||
421 !IsYUVOrNative(video_frame->format())) { 414 !IsYUVOrNative(video_frame->format())) {
422 canvas->drawRect(dest, paint); 415 canvas->drawRect(dest, paint);
423 canvas->flush(); 416 canvas->flush();
424 return; 417 return;
425 } 418 }
426 419
427 SkBitmap* target_frame = nullptr; 420 SkBitmap* target_frame = nullptr;
428 if (canvas->getGrContext()) { 421
422 if (video_frame->format() == VideoFrame::NATIVE_TEXTURE) {
423 // Draw HW Video on both SW and HW Canvas.
424 // In SW Canvas case, rely on skia drawing Ganesh SkBitmap on SW SkCanvas.
dshwang 2015/01/14 20:32:13 As comment mentions, drawing ganesh SkBitmap on Sw
429 if (accelerated_last_frame_.isNull() || 425 if (accelerated_last_frame_.isNull() ||
430 video_frame->timestamp() != accelerated_last_frame_timestamp_) { 426 video_frame->timestamp() != accelerated_last_frame_timestamp_) {
431 if (video_frame->format() == VideoFrame::NATIVE_TEXTURE) { 427 DCHECK(context_3d.gl);
432 // Draw HW Video on HW Canvas. 428 DCHECK(context_3d.gr_context);
433 DCHECK(context_3d.gl); 429 if (accelerated_generator_) {
434 DCHECK(context_3d.gr_context); 430 // Reset SkBitmap used in SWVideo-to-HWCanvas path.
435 if (accelerated_generator_) { 431 accelerated_last_frame_.reset();
436 // Reset SkBitmap used in SWVideo-to-HWCanvas path. 432 accelerated_generator_ = nullptr;
437 accelerated_last_frame_.reset(); 433 }
438 accelerated_generator_ = nullptr; 434 if (!CopyVideoFrameTextureToSkBitmapTexture(
439 } 435 video_frame.get(), &accelerated_last_frame_, context_3d)) {
440 if (!CopyVideoFrameTextureToSkBitmapTexture( 436 NOTREACHED();
441 video_frame.get(), &accelerated_last_frame_, context_3d)) { 437 return;
442 NOTREACHED(); 438 }
443 return; 439 DCHECK(video_frame->visible_rect().width() ==
444 } 440 accelerated_last_frame_.width() &&
445 } else { 441 video_frame->visible_rect().height() ==
442 accelerated_last_frame_.height());
443
444 accelerated_last_frame_timestamp_ = video_frame->timestamp();
445 }
446 target_frame = &accelerated_last_frame_;
447 accelerated_frame_deleting_timer_.Reset();
448 } else if (canvas->getGrContext()) {
449 DCHECK(video_frame->format() != VideoFrame::NATIVE_TEXTURE);
450 if (accelerated_last_frame_.isNull() ||
451 video_frame->timestamp() != accelerated_last_frame_timestamp_) {
452 {
446 // Draw SW Video on HW Canvas. 453 // Draw SW Video on HW Canvas.
447 if (!accelerated_generator_ && !accelerated_last_frame_.isNull()) { 454 if (!accelerated_generator_ && !accelerated_last_frame_.isNull()) {
448 // Reset SkBitmap used in HWVideo-to-HWCanvas path. 455 // Reset SkBitmap used in HWVideo-to-HWCanvas path.
449 accelerated_last_frame_.reset(); 456 accelerated_last_frame_.reset();
450 } 457 }
451 accelerated_generator_ = new VideoImageGenerator(video_frame); 458 accelerated_generator_ = new VideoImageGenerator(video_frame);
452 459
453 // Note: This takes ownership of |accelerated_generator_|. 460 // Note: This takes ownership of |accelerated_generator_|.
454 if (!SkInstallDiscardablePixelRef(accelerated_generator_, 461 if (!SkInstallDiscardablePixelRef(accelerated_generator_,
455 &accelerated_last_frame_)) { 462 &accelerated_last_frame_)) {
456 NOTREACHED(); 463 NOTREACHED();
457 return; 464 return;
458 } 465 }
459 } 466 }
460 DCHECK(video_frame->visible_rect().width() == 467 DCHECK(video_frame->visible_rect().width() ==
461 accelerated_last_frame_.width() && 468 accelerated_last_frame_.width() &&
462 video_frame->visible_rect().height() == 469 video_frame->visible_rect().height() ==
463 accelerated_last_frame_.height()); 470 accelerated_last_frame_.height());
464 471
465 accelerated_last_frame_timestamp_ = video_frame->timestamp(); 472 accelerated_last_frame_timestamp_ = video_frame->timestamp();
466 } else if (accelerated_generator_) { 473 } else if (accelerated_generator_) {
467 accelerated_generator_->set_frame(video_frame); 474 accelerated_generator_->set_frame(video_frame);
468 } 475 }
469 target_frame = &accelerated_last_frame_; 476 target_frame = &accelerated_last_frame_;
470 accelerated_frame_deleting_timer_.Reset(); 477 accelerated_frame_deleting_timer_.Reset();
471 } else { 478 } else {
472 // Draw both SW and HW Video on SW Canvas. 479 // Draw SW Video on SW Canvas.
480 DCHECK(video_frame->format() != VideoFrame::NATIVE_TEXTURE);
473 if (last_frame_.isNull() || 481 if (last_frame_.isNull() ||
474 video_frame->timestamp() != last_frame_timestamp_) { 482 video_frame->timestamp() != last_frame_timestamp_) {
475 // Check if |bitmap| needs to be (re)allocated. 483 // Check if |bitmap| needs to be (re)allocated.
476 if (last_frame_.isNull() || 484 if (last_frame_.isNull() ||
477 last_frame_.width() != video_frame->visible_rect().width() || 485 last_frame_.width() != video_frame->visible_rect().width() ||
478 last_frame_.height() != video_frame->visible_rect().height()) { 486 last_frame_.height() != video_frame->visible_rect().height()) {
479 last_frame_.allocN32Pixels(video_frame->visible_rect().width(), 487 last_frame_.allocN32Pixels(video_frame->visible_rect().width(),
480 video_frame->visible_rect().height()); 488 video_frame->visible_rect().height());
481 last_frame_.setIsVolatile(true); 489 last_frame_.setIsVolatile(true);
482 } 490 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 if (need_transform) 543 if (need_transform)
536 canvas->restore(); 544 canvas->restore();
537 canvas->flush(); 545 canvas->flush();
538 // SkCanvas::flush() causes the generator to generate SkImage, so delete 546 // SkCanvas::flush() causes the generator to generate SkImage, so delete
539 // |video_frame| not to be outlived. 547 // |video_frame| not to be outlived.
540 if (canvas->getGrContext() && accelerated_generator_) 548 if (canvas->getGrContext() && accelerated_generator_)
541 accelerated_generator_->set_frame(nullptr); 549 accelerated_generator_->set_frame(nullptr);
542 } 550 }
543 551
544 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, 552 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
545 SkCanvas* canvas) { 553 SkCanvas* canvas,
554 const Context3D& context_3d) {
546 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff, 555 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff,
547 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, Context3D()); 556 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d);
548 } 557 }
549 558
550 // static 559 // static
551 void SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture( 560 void SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture(
552 gpu::gles2::GLES2Interface* gl, 561 gpu::gles2::GLES2Interface* gl,
553 VideoFrame* video_frame, 562 VideoFrame* video_frame,
554 unsigned int texture, 563 unsigned int texture,
555 unsigned int level, 564 unsigned int level,
556 unsigned int internal_format, 565 unsigned int internal_format,
557 unsigned int type, 566 unsigned int type,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 last_frame_timestamp_ = media::kNoTimestamp(); 600 last_frame_timestamp_ = media::kNoTimestamp();
592 } 601 }
593 602
594 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() { 603 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() {
595 accelerated_last_frame_.reset(); 604 accelerated_last_frame_.reset();
596 accelerated_generator_ = nullptr; 605 accelerated_generator_ = nullptr;
597 accelerated_last_frame_timestamp_ = media::kNoTimestamp(); 606 accelerated_last_frame_timestamp_ = media::kNoTimestamp();
598 } 607 }
599 608
600 } // namespace media 609 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698