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

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: danakj review, build fix 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
« no previous file with comments | « cc/output/gl_renderer.cc ('k') | cc/output/shader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) + 416 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
417 video_frame->stride(media::VideoFrame::kUPlane) * i; 417 video_frame->stride(media::VideoFrame::kUPlane) * i;
418 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) + 418 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
419 video_frame->stride(media::VideoFrame::kVPlane) * i; 419 video_frame->stride(media::VideoFrame::kVPlane) * i;
420 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane); 420 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
421 ++j) { 421 ++j) {
422 u_row[j] = (u_value += 3); 422 u_row[j] = (u_value += 3);
423 v_row[j] = (v_value += 5); 423 v_row[j] = (v_value += 5);
424 } 424 }
425 } 425 }
426 uint8 alpha_value = is_transparent ? 0 : 128;
426 CreateTestYUVVideoDrawQuad_FromVideoFrame( 427 CreateTestYUVVideoDrawQuad_FromVideoFrame(
427 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass); 428 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
428 } 429 }
429 430
430 void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState* shared_state, 431 void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState* shared_state,
431 media::VideoFrame::Format format, 432 media::VideoFrame::Format format,
432 bool is_transparent, 433 bool is_transparent,
433 const gfx::RectF& tex_coord_rect, 434 const gfx::RectF& tex_coord_rect,
434 uint8 y, 435 uint8 y,
435 uint8 u, 436 uint8 u,
436 uint8 v, 437 uint8 v,
437 RenderPass* render_pass) { 438 RenderPass* render_pass) {
(...skipping 11 matching lines...) Expand all
449 video_frame->rows(media::VideoFrame::kYPlane)); 450 video_frame->rows(media::VideoFrame::kYPlane));
450 memset(video_frame->data(media::VideoFrame::kUPlane), 451 memset(video_frame->data(media::VideoFrame::kUPlane),
451 u, 452 u,
452 video_frame->stride(media::VideoFrame::kUPlane) * 453 video_frame->stride(media::VideoFrame::kUPlane) *
453 video_frame->rows(media::VideoFrame::kUPlane)); 454 video_frame->rows(media::VideoFrame::kUPlane));
454 memset(video_frame->data(media::VideoFrame::kVPlane), 455 memset(video_frame->data(media::VideoFrame::kVPlane),
455 v, 456 v,
456 video_frame->stride(media::VideoFrame::kVPlane) * 457 video_frame->stride(media::VideoFrame::kVPlane) *
457 video_frame->rows(media::VideoFrame::kVPlane)); 458 video_frame->rows(media::VideoFrame::kVPlane));
458 459
460 uint8 alpha_value = is_transparent ? 0 : 128;
459 CreateTestYUVVideoDrawQuad_FromVideoFrame( 461 CreateTestYUVVideoDrawQuad_FromVideoFrame(
460 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass); 462 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
463 }
464
465 void CreateEdgeBleedPass(media::VideoFrame::Format format,
466 RenderPassList* pass_list) {
467 gfx::Rect rect(200, 200);
468
469 RenderPassId id(1, 1);
470 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
471
472 // Scale the video up so that bilinear filtering kicks in to sample more
473 // than just nearest neighbor would.
474 gfx::Transform scale_by_2;
475 scale_by_2.Scale(2.f, 2.f);
476 gfx::Rect half_rect(100, 100);
477 SharedQuadState* shared_state =
478 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
479
480 gfx::Size background_size(200, 200);
481 gfx::Rect green_rect(16, 20, 100, 100);
482 gfx::RectF tex_coord_rect(
483 static_cast<float>(green_rect.x()) / background_size.width(),
484 static_cast<float>(green_rect.y()) / background_size.height(),
485 static_cast<float>(green_rect.width()) / background_size.width(),
486 static_cast<float>(green_rect.height()) / background_size.height());
487
488 // YUV of (149,43,21) should be green (0,255,0) in RGB.
489 // Create a video frame that has a non-green background rect, with a
490 // green sub-rectangle that should be the only thing displayed in
491 // the final image. Bleeding will appear on all four sides of the video
492 // if the tex coords are not clamped.
493 CreateTestYUVVideoDrawQuad_TwoColor(shared_state, format, false,
494 tex_coord_rect, background_size, 0, 0,
495 0, green_rect, 149, 43, 21, pass.get());
496 pass_list->push_back(pass.Pass());
497 }
498
499 // Creates a video frame of size background_size filled with yuv_background,
500 // and then draws a foreground rectangle in a different color on top of
501 // that. The foreground rectangle must have coordinates that are divisible
502 // by 2 because YUV is a block format.
503 void CreateTestYUVVideoDrawQuad_TwoColor(const SharedQuadState* shared_state,
504 media::VideoFrame::Format format,
505 bool is_transparent,
506 const gfx::RectF& tex_coord_rect,
507 const gfx::Size& background_size,
508 uint8 y_background,
509 uint8 u_background,
510 uint8 v_background,
511 const gfx::Rect& foreground_rect,
512 uint8 y_foreground,
513 uint8 u_foreground,
514 uint8 v_foreground,
515 RenderPass* render_pass) {
516 const gfx::Rect rect(background_size);
517
518 scoped_refptr<media::VideoFrame> video_frame =
519 media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
520 foreground_rect.size(),
521 base::TimeDelta());
522
523 int planes[] = {media::VideoFrame::kYPlane,
524 media::VideoFrame::kUPlane,
525 media::VideoFrame::kVPlane};
526 uint8 yuv_background[] = {y_background, u_background, v_background};
527 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
528 int sample_size[] = {1, 2, 2};
529
530 for (int i = 0; i < 3; ++i) {
531 memset(video_frame->data(planes[i]), yuv_background[i],
532 video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
533 }
534
535 for (int i = 0; i < 3; ++i) {
536 // Since yuv encoding uses block encoding, widths have to be divisible
537 // by the sample size in order for this function to behave properly.
538 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
539 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
540 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
541 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
542
543 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
544 foreground_rect.y() / sample_size[i],
545 foreground_rect.width() / sample_size[i],
546 foreground_rect.height() / sample_size[i]);
547 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
548 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
549 size_t offset = y * video_frame->stride(planes[i]) + x;
550 video_frame->data(planes[i])[offset] = yuv_foreground[i];
551 }
552 }
553 }
554
555 uint8 alpha_value = 255;
556 CreateTestYUVVideoDrawQuad_FromVideoFrame(
557 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
461 } 558 }
462 559
463 void CreateTestYUVVideoDrawQuad_FromVideoFrame( 560 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
464 const SharedQuadState* shared_state, 561 const SharedQuadState* shared_state,
465 scoped_refptr<media::VideoFrame> video_frame, 562 scoped_refptr<media::VideoFrame> video_frame,
466 bool is_transparent, 563 uint8 alpha_value,
467 const gfx::RectF& tex_coord_rect, 564 const gfx::RectF& tex_coord_rect,
468 RenderPass* render_pass) { 565 RenderPass* render_pass) {
469 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A); 566 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
470 const YUVVideoDrawQuad::ColorSpace color_space = 567 const YUVVideoDrawQuad::ColorSpace color_space =
471 (video_frame->format() == media::VideoFrame::YV12J 568 (video_frame->format() == media::VideoFrame::YV12J
472 ? YUVVideoDrawQuad::REC_601_JPEG 569 ? YUVVideoDrawQuad::REC_601_JPEG
473 : YUVVideoDrawQuad::REC_601); 570 : YUVVideoDrawQuad::REC_601);
474 const gfx::Rect rect(this->device_viewport_size_); 571 const gfx::Rect rect(shared_state->content_bounds);
475 const gfx::Rect opaque_rect(0, 0, 0, 0); 572 const gfx::Rect opaque_rect(0, 0, 0, 0);
476 573
477 if (with_alpha) 574 if (with_alpha)
478 memset(video_frame->data(media::VideoFrame::kAPlane), 575 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
479 is_transparent ? 0 : 128,
480 video_frame->stride(media::VideoFrame::kAPlane) * 576 video_frame->stride(media::VideoFrame::kAPlane) *
481 video_frame->rows(media::VideoFrame::kAPlane)); 577 video_frame->rows(media::VideoFrame::kAPlane));
482 578
483 VideoFrameExternalResources resources = 579 VideoFrameExternalResources resources =
484 video_resource_updater_->CreateExternalResourcesFromVideoFrame( 580 video_resource_updater_->CreateExternalResourcesFromVideoFrame(
485 video_frame); 581 video_frame);
486 582
487 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type); 583 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
488 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), 584 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
489 resources.mailboxes.size()); 585 resources.mailboxes.size());
(...skipping 18 matching lines...) Expand all
508 ResourceProvider::ResourceId a_resource = 0; 604 ResourceProvider::ResourceId a_resource = 0;
509 if (with_alpha) { 605 if (with_alpha) {
510 a_resource = resource_provider_->CreateResourceFromTextureMailbox( 606 a_resource = resource_provider_->CreateResourceFromTextureMailbox(
511 resources.mailboxes[media::VideoFrame::kAPlane], 607 resources.mailboxes[media::VideoFrame::kAPlane],
512 SingleReleaseCallbackImpl::Create( 608 SingleReleaseCallbackImpl::Create(
513 resources.release_callbacks[media::VideoFrame::kAPlane])); 609 resources.release_callbacks[media::VideoFrame::kAPlane]));
514 } 610 }
515 611
516 YUVVideoDrawQuad* yuv_quad = 612 YUVVideoDrawQuad* yuv_quad =
517 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); 613 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
518 yuv_quad->SetNew(shared_state, 614 yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect,
519 rect, 615 video_frame->coded_size(), y_resource, u_resource,
520 opaque_rect, 616 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 } 617 }
529 618
530 void SetUp() override { 619 void SetUp() override {
531 GLRendererPixelTest::SetUp(); 620 GLRendererPixelTest::SetUp();
532 video_resource_updater_.reset(new VideoResourceUpdater( 621 video_resource_updater_.reset(new VideoResourceUpdater(
533 output_surface_->context_provider(), resource_provider_.get())); 622 output_surface_->context_provider(), resource_provider_.get()));
534 } 623 }
535 624
536 private: 625 private:
537 scoped_ptr<VideoResourceUpdater> video_resource_updater_; 626 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 pass.get()); 724 pass.get());
636 725
637 RenderPassList pass_list; 726 RenderPassList pass_list;
638 pass_list.push_back(pass.Pass()); 727 pass_list.push_back(pass.Pass());
639 728
640 EXPECT_TRUE(this->RunPixelTest(&pass_list, 729 EXPECT_TRUE(this->RunPixelTest(&pass_list,
641 base::FilePath(FILE_PATH_LITERAL("green.png")), 730 base::FilePath(FILE_PATH_LITERAL("green.png")),
642 FuzzyPixelOffByOneComparator(true))); 731 FuzzyPixelOffByOneComparator(true)));
643 } 732 }
644 733
734 // Test that a YUV video doesn't bleed outside of its tex coords when the
735 // tex coord rect is only a partial subrectangle of the coded contents.
736 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
737 RenderPassList pass_list;
738 CreateEdgeBleedPass(media::VideoFrame::YV12J, &pass_list);
739 EXPECT_TRUE(this->RunPixelTest(&pass_list,
740 base::FilePath(FILE_PATH_LITERAL("green.png")),
741 FuzzyPixelOffByOneComparator(true)));
742 }
743
744 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
745 RenderPassList pass_list;
746 CreateEdgeBleedPass(media::VideoFrame::YV12A, &pass_list);
747 EXPECT_TRUE(this->RunPixelTest(&pass_list,
748 base::FilePath(FILE_PATH_LITERAL("green.png")),
749 FuzzyPixelOffByOneComparator(true)));
750 }
751
645 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { 752 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
646 gfx::Rect rect(this->device_viewport_size_); 753 gfx::Rect rect(this->device_viewport_size_);
647 754
648 RenderPassId id(1, 1); 755 RenderPassId id(1, 1);
649 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 756 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
650 757
651 SharedQuadState* shared_state = 758 SharedQuadState* shared_state =
652 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); 759 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
653 760
654 // Dark grey in JPEG color range (in MPEG, this is black). 761 // 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( 2526 EXPECT_TRUE(this->RunPixelTest(
2420 &pass_list, 2527 &pass_list,
2421 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), 2528 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2422 FuzzyPixelOffByOneComparator(true))); 2529 FuzzyPixelOffByOneComparator(true)));
2423 } 2530 }
2424 2531
2425 #endif // !defined(OS_ANDROID) 2532 #endif // !defined(OS_ANDROID)
2426 2533
2427 } // namespace 2534 } // namespace
2428 } // namespace cc 2535 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/gl_renderer.cc ('k') | cc/output/shader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698