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

Side by Side Diff: cc/output/renderer_pixeltest.cc

Issue 881963002: Clamp YUV videos to their visible size in the shader (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add test, fix bugs 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 "base/message_loop/message_loop.h" 5 #include "base/message_loop/message_loop.h"
6 #include "cc/layers/append_quads_data.h" 6 #include "cc/layers/append_quads_data.h"
7 #include "cc/output/gl_renderer.h" 7 #include "cc/output/gl_renderer.h"
8 #include "cc/quads/draw_quad.h" 8 #include "cc/quads/draw_quad.h"
9 #include "cc/quads/picture_draw_quad.h" 9 #include "cc/quads/picture_draw_quad.h"
10 #include "cc/quads/texture_draw_quad.h" 10 #include "cc/quads/texture_draw_quad.h"
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 video_frame->rows(media::VideoFrame::kUPlane)); 453 video_frame->rows(media::VideoFrame::kUPlane));
454 memset(video_frame->data(media::VideoFrame::kVPlane), 454 memset(video_frame->data(media::VideoFrame::kVPlane),
455 v, 455 v,
456 video_frame->stride(media::VideoFrame::kVPlane) * 456 video_frame->stride(media::VideoFrame::kVPlane) *
457 video_frame->rows(media::VideoFrame::kVPlane)); 457 video_frame->rows(media::VideoFrame::kVPlane));
458 458
459 CreateTestYUVVideoDrawQuad_FromVideoFrame( 459 CreateTestYUVVideoDrawQuad_FromVideoFrame(
460 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass); 460 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass);
461 } 461 }
462 462
463 void CreateTestYUVVideoDrawQuad_TwoColor(const SharedQuadState* shared_state,
danakj 2015/02/02 18:43:03 can you leave a comment in here somewhere that exp
464 media::VideoFrame::Format format,
465 bool is_transparent,
466 const gfx::RectF& tex_coord_rect,
467 const gfx::Size& background_size,
468 uint8 y_background,
469 uint8 u_background,
470 uint8 v_background,
471 const gfx::Rect& foreground_rect,
472 uint8 y_foreground,
473 uint8 u_foreground,
474 uint8 v_foreground,
475 RenderPass* render_pass) {
476 const gfx::Rect rect(background_size);
477
478 scoped_refptr<media::VideoFrame> video_frame =
479 media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
480 foreground_rect.size(),
481 base::TimeDelta());
482
483 int planes[] = {media::VideoFrame::kYPlane,
484 media::VideoFrame::kUPlane,
485 media::VideoFrame::kVPlane};
486 uint8 yuv_background[] = {y_background, u_background, v_background};
487 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
488 int sample_size[] = {1, 2, 2};
489
490 for (int i = 0; i < 3; ++i) {
491 memset(video_frame->data(planes[i]), yuv_background[i],
492 video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
493 }
494
495 for (int i = 0; i < 3; ++i) {
496 // Since yuv encoding uses block encoding, widths have to be divisible
497 // by the sample size in order for this function to behave properly.
498 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
499 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
500 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
501 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
502
503 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
504 foreground_rect.y() / sample_size[i],
505 foreground_rect.width() / sample_size[i],
506 foreground_rect.height() / sample_size[i]);
507 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
508 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
509 size_t offset = y * video_frame->stride(planes[i]) + x;
510 video_frame->data(planes[i])[offset] = yuv_foreground[i];
511 }
512 }
513 }
514
515 CreateTestYUVVideoDrawQuad_FromVideoFrame(
516 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass);
517 }
518
463 void CreateTestYUVVideoDrawQuad_FromVideoFrame( 519 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
464 const SharedQuadState* shared_state, 520 const SharedQuadState* shared_state,
465 scoped_refptr<media::VideoFrame> video_frame, 521 scoped_refptr<media::VideoFrame> video_frame,
466 bool is_transparent, 522 bool is_transparent,
467 const gfx::RectF& tex_coord_rect, 523 const gfx::RectF& tex_coord_rect,
468 RenderPass* render_pass) { 524 RenderPass* render_pass) {
469 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A); 525 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
470 const YUVVideoDrawQuad::ColorSpace color_space = 526 const YUVVideoDrawQuad::ColorSpace color_space =
471 (video_frame->format() == media::VideoFrame::YV12J 527 (video_frame->format() == media::VideoFrame::YV12J
472 ? YUVVideoDrawQuad::REC_601_JPEG 528 ? YUVVideoDrawQuad::REC_601_JPEG
473 : YUVVideoDrawQuad::REC_601); 529 : YUVVideoDrawQuad::REC_601);
474 const gfx::Rect rect(this->device_viewport_size_); 530 const gfx::Rect rect(shared_state->content_bounds);
enne (OOO) 2015/01/31 01:32:14 Without this change, the video quads were ending u
475 const gfx::Rect opaque_rect(0, 0, 0, 0); 531 const gfx::Rect opaque_rect(0, 0, 0, 0);
476 532
477 if (with_alpha) 533 if (with_alpha)
478 memset(video_frame->data(media::VideoFrame::kAPlane), 534 memset(video_frame->data(media::VideoFrame::kAPlane),
479 is_transparent ? 0 : 128, 535 is_transparent ? 0 : 128,
480 video_frame->stride(media::VideoFrame::kAPlane) * 536 video_frame->stride(media::VideoFrame::kAPlane) *
481 video_frame->rows(media::VideoFrame::kAPlane)); 537 video_frame->rows(media::VideoFrame::kAPlane));
482 538
483 VideoFrameExternalResources resources = 539 VideoFrameExternalResources resources =
484 video_resource_updater_->CreateExternalResourcesFromVideoFrame( 540 video_resource_updater_->CreateExternalResourcesFromVideoFrame(
(...skipping 23 matching lines...) Expand all
508 ResourceProvider::ResourceId a_resource = 0; 564 ResourceProvider::ResourceId a_resource = 0;
509 if (with_alpha) { 565 if (with_alpha) {
510 a_resource = resource_provider_->CreateResourceFromTextureMailbox( 566 a_resource = resource_provider_->CreateResourceFromTextureMailbox(
511 resources.mailboxes[media::VideoFrame::kAPlane], 567 resources.mailboxes[media::VideoFrame::kAPlane],
512 SingleReleaseCallbackImpl::Create( 568 SingleReleaseCallbackImpl::Create(
513 resources.release_callbacks[media::VideoFrame::kAPlane])); 569 resources.release_callbacks[media::VideoFrame::kAPlane]));
514 } 570 }
515 571
516 YUVVideoDrawQuad* yuv_quad = 572 YUVVideoDrawQuad* yuv_quad =
517 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); 573 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
518 yuv_quad->SetNew(shared_state, 574 yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect,
519 rect, 575 video_frame->coded_size(), y_resource, u_resource,
520 opaque_rect, 576 v_resource, a_resource, color_space);
521 rect,
522 tex_coord_rect,
523 y_resource,
524 u_resource,
525 v_resource,
526 a_resource,
527 color_space);
528 } 577 }
529 578
530 void SetUp() override { 579 void SetUp() override {
531 GLRendererPixelTest::SetUp(); 580 GLRendererPixelTest::SetUp();
532 video_resource_updater_.reset(new VideoResourceUpdater( 581 video_resource_updater_.reset(new VideoResourceUpdater(
533 output_surface_->context_provider(), resource_provider_.get())); 582 output_surface_->context_provider(), resource_provider_.get()));
534 } 583 }
535 584
536 private: 585 private:
537 scoped_ptr<VideoResourceUpdater> video_resource_updater_; 586 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 pass.get()); 684 pass.get());
636 685
637 RenderPassList pass_list; 686 RenderPassList pass_list;
638 pass_list.push_back(pass.Pass()); 687 pass_list.push_back(pass.Pass());
639 688
640 EXPECT_TRUE(this->RunPixelTest(&pass_list, 689 EXPECT_TRUE(this->RunPixelTest(&pass_list,
641 base::FilePath(FILE_PATH_LITERAL("green.png")), 690 base::FilePath(FILE_PATH_LITERAL("green.png")),
642 FuzzyPixelOffByOneComparator(true))); 691 FuzzyPixelOffByOneComparator(true)));
643 } 692 }
644 693
694 // Test that a YUV video doesn't bleed outside of its tex coords when the
danakj 2015/02/02 18:43:03 Should we test YUVA shader too?
695 // tex coord rect is only a partial subrectangle of the coded contents.
696 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
697 gfx::Rect rect(200, 200);
698
699 RenderPassId id(1, 1);
700 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
701
702 // Scale the video up so that bilinear filtering kicks in to sample more
703 // than just nearest neighbor would.
704 gfx::Transform scale_by_2;
705 scale_by_2.Scale(2.f, 2.f);
706 gfx::Rect half_rect(100, 100);
707 SharedQuadState* shared_state =
708 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
709
710 gfx::Size background_size(200, 200);
711 gfx::Rect green_rect(16, 20, 100, 100);
712 gfx::RectF tex_coord_rect(
713 static_cast<float>(green_rect.x()) / background_size.width(),
714 static_cast<float>(green_rect.y()) / background_size.height(),
715 static_cast<float>(green_rect.width()) / background_size.width(),
716 static_cast<float>(green_rect.height()) / background_size.height());
717
718 // YUV of (149,43,21) should be green (0,255,0) in RGB.
719 // Create a video frame that has a non-green background rect, with a
720 // green sub-rectangle that should be the only thing displayed in
721 // the final image. Bleeding will appear on all four sides of the video
722 // if the tex coords are not clamped.
723 CreateTestYUVVideoDrawQuad_TwoColor(
724 shared_state, media::VideoFrame::YV12J, false, tex_coord_rect,
725 background_size, 0, 0, 0, green_rect, 149, 43, 21, pass.get());
726
727 RenderPassList pass_list;
728 pass_list.push_back(pass.Pass());
729
730 EXPECT_TRUE(this->RunPixelTest(&pass_list,
731 base::FilePath(FILE_PATH_LITERAL("green.png")),
732 FuzzyPixelOffByOneComparator(true)));
733 }
734
645 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { 735 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
646 gfx::Rect rect(this->device_viewport_size_); 736 gfx::Rect rect(this->device_viewport_size_);
647 737
648 RenderPassId id(1, 1); 738 RenderPassId id(1, 1);
649 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 739 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
650 740
651 SharedQuadState* shared_state = 741 SharedQuadState* shared_state =
652 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); 742 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
653 743
654 // Dark grey in JPEG color range (in MPEG, this is black). 744 // Dark grey in JPEG color range (in MPEG, this is black).
(...skipping 1764 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 EXPECT_TRUE(this->RunPixelTest( 2509 EXPECT_TRUE(this->RunPixelTest(
2420 &pass_list, 2510 &pass_list,
2421 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), 2511 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2422 FuzzyPixelOffByOneComparator(true))); 2512 FuzzyPixelOffByOneComparator(true)));
2423 } 2513 }
2424 2514
2425 #endif // !defined(OS_ANDROID) 2515 #endif // !defined(OS_ANDROID)
2426 2516
2427 } // namespace 2517 } // namespace
2428 } // namespace cc 2518 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/gl_renderer.cc ('k') | cc/output/shader.h » ('j') | cc/output/shader.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698