OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |