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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/output/gl_renderer.cc ('k') | cc/output/shader.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/renderer_pixeltest.cc
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index 08a40530eb4753c1257a963e72bcc15c5a2f0af3..d503cc4462160623e84d19d49898a5875334b475 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -423,8 +423,9 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
v_row[j] = (v_value += 5);
}
}
+ uint8 alpha_value = is_transparent ? 0 : 128;
CreateTestYUVVideoDrawQuad_FromVideoFrame(
- shared_state, video_frame, is_transparent, tex_coord_rect, render_pass);
+ shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
}
void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState* shared_state,
@@ -456,14 +457,110 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
video_frame->stride(media::VideoFrame::kVPlane) *
video_frame->rows(media::VideoFrame::kVPlane));
+ uint8 alpha_value = is_transparent ? 0 : 128;
CreateTestYUVVideoDrawQuad_FromVideoFrame(
- shared_state, video_frame, is_transparent, tex_coord_rect, render_pass);
+ shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
+ }
+
+ void CreateEdgeBleedPass(media::VideoFrame::Format format,
+ RenderPassList* pass_list) {
+ gfx::Rect rect(200, 200);
+
+ RenderPassId id(1, 1);
+ scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+
+ // Scale the video up so that bilinear filtering kicks in to sample more
+ // than just nearest neighbor would.
+ gfx::Transform scale_by_2;
+ scale_by_2.Scale(2.f, 2.f);
+ gfx::Rect half_rect(100, 100);
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
+
+ gfx::Size background_size(200, 200);
+ gfx::Rect green_rect(16, 20, 100, 100);
+ gfx::RectF tex_coord_rect(
+ static_cast<float>(green_rect.x()) / background_size.width(),
+ static_cast<float>(green_rect.y()) / background_size.height(),
+ static_cast<float>(green_rect.width()) / background_size.width(),
+ static_cast<float>(green_rect.height()) / background_size.height());
+
+ // YUV of (149,43,21) should be green (0,255,0) in RGB.
+ // Create a video frame that has a non-green background rect, with a
+ // green sub-rectangle that should be the only thing displayed in
+ // the final image. Bleeding will appear on all four sides of the video
+ // if the tex coords are not clamped.
+ CreateTestYUVVideoDrawQuad_TwoColor(shared_state, format, false,
+ tex_coord_rect, background_size, 0, 0,
+ 0, green_rect, 149, 43, 21, pass.get());
+ pass_list->push_back(pass.Pass());
+ }
+
+ // Creates a video frame of size background_size filled with yuv_background,
+ // and then draws a foreground rectangle in a different color on top of
+ // that. The foreground rectangle must have coordinates that are divisible
+ // by 2 because YUV is a block format.
+ void CreateTestYUVVideoDrawQuad_TwoColor(const SharedQuadState* shared_state,
+ media::VideoFrame::Format format,
+ bool is_transparent,
+ const gfx::RectF& tex_coord_rect,
+ const gfx::Size& background_size,
+ uint8 y_background,
+ uint8 u_background,
+ uint8 v_background,
+ const gfx::Rect& foreground_rect,
+ uint8 y_foreground,
+ uint8 u_foreground,
+ uint8 v_foreground,
+ RenderPass* render_pass) {
+ const gfx::Rect rect(background_size);
+
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
+ foreground_rect.size(),
+ base::TimeDelta());
+
+ int planes[] = {media::VideoFrame::kYPlane,
+ media::VideoFrame::kUPlane,
+ media::VideoFrame::kVPlane};
+ uint8 yuv_background[] = {y_background, u_background, v_background};
+ uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
+ int sample_size[] = {1, 2, 2};
+
+ for (int i = 0; i < 3; ++i) {
+ memset(video_frame->data(planes[i]), yuv_background[i],
+ video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ // Since yuv encoding uses block encoding, widths have to be divisible
+ // by the sample size in order for this function to behave properly.
+ DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
+ DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
+ DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
+ DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
+
+ gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
+ foreground_rect.y() / sample_size[i],
+ foreground_rect.width() / sample_size[i],
+ foreground_rect.height() / sample_size[i]);
+ for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
+ for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
+ size_t offset = y * video_frame->stride(planes[i]) + x;
+ video_frame->data(planes[i])[offset] = yuv_foreground[i];
+ }
+ }
+ }
+
+ uint8 alpha_value = 255;
+ CreateTestYUVVideoDrawQuad_FromVideoFrame(
+ shared_state, video_frame, alpha_value, tex_coord_rect, render_pass);
}
void CreateTestYUVVideoDrawQuad_FromVideoFrame(
const SharedQuadState* shared_state,
scoped_refptr<media::VideoFrame> video_frame,
- bool is_transparent,
+ uint8 alpha_value,
const gfx::RectF& tex_coord_rect,
RenderPass* render_pass) {
const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
@@ -471,12 +568,11 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
(video_frame->format() == media::VideoFrame::YV12J
? YUVVideoDrawQuad::REC_601_JPEG
: YUVVideoDrawQuad::REC_601);
- const gfx::Rect rect(this->device_viewport_size_);
+ const gfx::Rect rect(shared_state->content_bounds);
const gfx::Rect opaque_rect(0, 0, 0, 0);
if (with_alpha)
- memset(video_frame->data(media::VideoFrame::kAPlane),
- is_transparent ? 0 : 128,
+ memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
video_frame->stride(media::VideoFrame::kAPlane) *
video_frame->rows(media::VideoFrame::kAPlane));
@@ -515,16 +611,9 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
YUVVideoDrawQuad* yuv_quad =
render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
- yuv_quad->SetNew(shared_state,
- rect,
- opaque_rect,
- rect,
- tex_coord_rect,
- y_resource,
- u_resource,
- v_resource,
- a_resource,
- color_space);
+ yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect,
+ video_frame->coded_size(), y_resource, u_resource,
+ v_resource, a_resource, color_space);
}
void SetUp() override {
@@ -642,6 +731,24 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
FuzzyPixelOffByOneComparator(true)));
}
+// Test that a YUV video doesn't bleed outside of its tex coords when the
+// tex coord rect is only a partial subrectangle of the coded contents.
+TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
+ RenderPassList pass_list;
+ CreateEdgeBleedPass(media::VideoFrame::YV12J, &pass_list);
+ EXPECT_TRUE(this->RunPixelTest(&pass_list,
+ base::FilePath(FILE_PATH_LITERAL("green.png")),
+ FuzzyPixelOffByOneComparator(true)));
+}
+
+TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
+ RenderPassList pass_list;
+ CreateEdgeBleedPass(media::VideoFrame::YV12A, &pass_list);
+ EXPECT_TRUE(this->RunPixelTest(&pass_list,
+ base::FilePath(FILE_PATH_LITERAL("green.png")),
+ FuzzyPixelOffByOneComparator(true)));
+}
+
TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
gfx::Rect rect(this->device_viewport_size_);
« 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