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

Unified Diff: cc/output/renderer_pixeltest.cc

Issue 2418173002: Fix HTML5 video blurry (Closed)
Patch Set: fix nits Created 4 years, 2 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_draw_cache.h ('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 c62ae058d00de3a93b6a68d2ecc1a2a8cbc5a1c1..d9b1be517e0422b631f38b21621174ed36532340 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "base/message_loop/message_loop.h"
+#include "base/strings/string_split.h"
#include "cc/base/math_util.h"
#include "cc/output/gl_renderer.h"
#include "cc/quads/draw_quad.h"
@@ -16,6 +17,7 @@
#include "cc/test/fake_raster_source.h"
#include "cc/test/fake_recording_source.h"
#include "cc/test/pixel_test.h"
+#include "cc/test/test_in_process_context_provider.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "media/base/video_frame.h"
#include "third_party/skia/include/core/SkColorPriv.h"
@@ -217,72 +219,85 @@ void CreateTestYUVVideoDrawQuad_FromVideoFrame(
video_frame->rows(media::VideoFrame::kAPlane));
}
- VideoFrameExternalResources resources =
+ VideoFrameExternalResources external_resources =
video_resource_updater->CreateExternalResourcesFromVideoFrame(
video_frame);
- EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
- EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
- resources.mailboxes.size());
- EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
- resources.release_callbacks.size());
-
- ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kYPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kYPlane]));
- ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kUPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kUPlane]));
- ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kVPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kVPlane]));
- ResourceId a_resource = 0;
- if (with_alpha) {
- a_resource = resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kAPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kAPlane]));
+ ResourceProvider::ResourceIdArray resource_ids;
+ resource_ids.reserve(external_resources.mailboxes.size());
+ for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) {
+ ResourceId resource_id =
+ resource_provider->CreateResourceFromTextureMailbox(
+ external_resources.mailboxes[i],
+ SingleReleaseCallbackImpl::Create(
+ external_resources.release_callbacks[i]),
+ external_resources.read_lock_fences_enabled);
+ resource_ids.push_back(resource_id);
}
- const gfx::Size ya_tex_size = video_frame->coded_size();
- const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
- video_frame->format(), media::VideoFrame::kUPlane,
- video_frame->coded_size());
- DCHECK(uv_tex_size == media::VideoFrame::PlaneSize(
- video_frame->format(), media::VideoFrame::kVPlane,
- video_frame->coded_size()));
- if (with_alpha) {
- DCHECK(ya_tex_size == media::VideoFrame::PlaneSize(
- video_frame->format(), media::VideoFrame::kAPlane,
- video_frame->coded_size()));
- }
-
- gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(),
- tex_coord_rect.y() * ya_tex_size.height(),
- tex_coord_rect.width() * ya_tex_size.width(),
- tex_coord_rect.height() * ya_tex_size.height());
- gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(),
- tex_coord_rect.y() * uv_tex_size.height(),
- tex_coord_rect.width() * uv_tex_size.width(),
- tex_coord_rect.height() * uv_tex_size.height());
-
- YUVVideoDrawQuad* yuv_quad =
- render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
- uint32_t bits_per_channel = 8;
- if (video_frame->format() == media::PIXEL_FORMAT_YUV420P10 ||
- video_frame->format() == media::PIXEL_FORMAT_YUV422P10 ||
- video_frame->format() == media::PIXEL_FORMAT_YUV444P10) {
- bits_per_channel = 10;
+ switch (external_resources.type) {
+ case VideoFrameExternalResources::YUV_RESOURCE: {
+ EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
+ external_resources.mailboxes.size());
+ EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
+ external_resources.release_callbacks.size());
+ const gfx::Size ya_tex_size = video_frame->coded_size();
+ const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
+ video_frame->format(), media::VideoFrame::kUPlane,
+ video_frame->coded_size());
+ DCHECK(uv_tex_size ==
+ media::VideoFrame::PlaneSize(video_frame->format(),
+ media::VideoFrame::kVPlane,
+ video_frame->coded_size()));
+ if (with_alpha) {
+ DCHECK(ya_tex_size ==
+ media::VideoFrame::PlaneSize(video_frame->format(),
+ media::VideoFrame::kAPlane,
+ video_frame->coded_size()));
+ }
+ gfx::RectF ya_tex_coord_rect(
+ tex_coord_rect.x() * ya_tex_size.width(),
+ tex_coord_rect.y() * ya_tex_size.height(),
+ tex_coord_rect.width() * ya_tex_size.width(),
+ tex_coord_rect.height() * ya_tex_size.height());
+ gfx::RectF uv_tex_coord_rect(
+ tex_coord_rect.x() * uv_tex_size.width(),
+ tex_coord_rect.y() * uv_tex_size.height(),
+ tex_coord_rect.width() * uv_tex_size.width(),
+ tex_coord_rect.height() * uv_tex_size.height());
+
+ YUVVideoDrawQuad* yuv_quad =
+ render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
+ yuv_quad->SetNew(
+ shared_state, rect, opaque_rect, visible_rect, ya_tex_coord_rect,
+ uv_tex_coord_rect, ya_tex_size, uv_tex_size, resource_ids[0],
+ resource_ids[1],
+ resource_ids.size() > 2 ? resource_ids[2] : resource_ids[1],
+ resource_ids.size() > 3 ? resource_ids[3] : 0, color_space,
+ video_color_space, external_resources.offset,
+ external_resources.multiplier, external_resources.bits_per_channel);
+ break;
+ }
+ case VideoFrameExternalResources::RGBA_RESOURCE: {
+ EXPECT_EQ(1u, external_resources.mailboxes.size());
+ EXPECT_EQ(1u, external_resources.release_callbacks.size());
+ float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ TextureDrawQuad* texture_quad =
+ render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
+ texture_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
+ resource_ids[0], false, tex_coord_rect.origin(),
+ tex_coord_rect.bottom_right(), SK_ColorTRANSPARENT,
+ opacity, false, false, false);
+ break;
+ }
+ case VideoFrameExternalResources::NONE:
+ case VideoFrameExternalResources::RGB_RESOURCE:
+ case VideoFrameExternalResources::RGBA_PREMULTIPLIED_RESOURCE:
+ case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE:
+ case VideoFrameExternalResources::SOFTWARE_RESOURCE:
+ NOTREACHED();
+ break;
}
-
- yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
- ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
- uv_tex_size, y_resource, u_resource, v_resource, a_resource,
- color_space, video_color_space, 0.0f, 1.0f,
- bits_per_channel);
}
// Upshift video frame to 10 bit.
@@ -343,6 +358,8 @@ void CreateTestYUVVideoDrawQuad_Striped(
ResourceProvider* resource_provider) {
scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
format, rect.size(), rect, rect.size(), base::TimeDelta());
+ video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
+ media::COLOR_SPACE_JPEG);
// YUV values representing a striped pattern, for validating texture
// coordinates for sampling.
@@ -486,6 +503,7 @@ void CreateTestYUVVideoDrawQuad_Solid(
void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state,
media::ColorSpace video_frame_color_space,
const gfx::ColorSpace& video_color_space,
+ ResourceFormat y_format,
const gfx::RectF& tex_coord_rect,
uint8_t y,
uint8_t u,
@@ -505,8 +523,8 @@ void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state,
media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size());
ResourceId y_resource = resource_provider->CreateResource(
- rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT,
- resource_provider->YuvResourceFormat(8), gfx::ColorSpace());
+ rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, y_format,
+ gfx::ColorSpace());
ResourceId u_resource = resource_provider->CreateResource(
uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888,
gfx::ColorSpace());
@@ -1094,12 +1112,71 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
output_surface_->context_provider(), resource_provider_.get()));
}
+ void DisableOneComponentTextures() {
+ TestInProcessContextProvider* context_provider =
+ GetTestInProcessContextProvider();
+ context_provider->SetDisableOneComponentTextures(true);
+ }
+
std::unique_ptr<VideoResourceUpdater> video_resource_updater_;
+
+ protected:
+ TestInProcessContextProvider* GetTestInProcessContextProvider() {
+ return static_cast<TestInProcessContextProvider*>(
+ output_surface_->context_provider());
+ }
+};
+
+enum class HighbitTexture {
+ Y8,
+ RGBA_8888,
+ LUMINANCE_F16, // need --use-gpu-in-tests
};
class VideoGLRendererPixelHiLoTest
: public VideoGLRendererPixelTest,
- public ::testing::WithParamInterface<bool> {};
+ public ::testing::WithParamInterface<
+ ::testing::tuple<bool, HighbitTexture>> {
+ public:
+ void SetSupportHighbitTexture(HighbitTexture texture) {
+ TestInProcessContextProvider* context_provider =
+ GetTestInProcessContextProvider();
+ switch (texture) {
+ case HighbitTexture::Y8:
+ context_provider->SetDisableOneComponentTextures(false);
+ context_provider->SetSupportTextureHalfFloatLinear(false);
+ break;
+ case HighbitTexture::RGBA_8888:
+ context_provider->SetDisableOneComponentTextures(true);
+ context_provider->SetSupportTextureHalfFloatLinear(false);
+ break;
+ case HighbitTexture::LUMINANCE_F16:
+ context_provider->SetDisableOneComponentTextures(false);
+ context_provider->SetSupportTextureHalfFloatLinear(true);
+ break;
+ }
+ }
+
+ bool IsHalfFloatLinearSupported() {
+ if (extensions_.empty())
+ InitializeExtensions();
+
+ return extensions_.find("GL_OES_texture_half_float_linear") !=
+ extensions_.end();
+ }
+
+ private:
+ void InitializeExtensions() {
+ std::string extensions = GetTestInProcessContextProvider()
+ ->ContextGL()
+ ->GetRequestableExtensionsCHROMIUM();
+ std::vector<std::string> tokens = base::SplitString(
+ extensions, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ extensions_.insert(tokens.begin(), tokens.end());
+ }
+
+ std::set<std::string> extensions_;
+};
TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
gfx::Rect rect(this->device_viewport_size_);
@@ -1110,7 +1187,12 @@ TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
SharedQuadState* shared_state =
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
- bool highbit = GetParam();
+ const bool highbit = testing::get<0>(GetParam());
+ const HighbitTexture format = testing::get<1>(GetParam());
+ if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported())
+ return;
+
+ SetSupportHighbitTexture(format);
CreateTestYUVVideoDrawQuad_Striped(
shared_state, media::PIXEL_FORMAT_YV12, false, highbit,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
@@ -1119,10 +1201,19 @@ TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
- EXPECT_TRUE(
- this->RunPixelTest(&pass_list,
- base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
- FuzzyPixelOffByOneComparator(true)));
+ base::FilePath file_path =
+ base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png"));
+ // TODO(dshwang): investigate why results per configuraion are so different.
+ // crbug.com/622133
+ if (format == HighbitTexture::RGBA_8888) {
+ // Color space is so different, because this path doesn't respect video
+ // color profile.
+ file_path = base::FilePath(FILE_PATH_LITERAL("yuv_stripes_rgba.png"));
+ }
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list, file_path,
+ // All pixels can be off by two, but any more than that is an error.
+ FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0)));
}
TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
@@ -1136,7 +1227,12 @@ TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
SharedQuadState* shared_state =
CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
- bool highbit = GetParam();
+ const bool highbit = testing::get<0>(GetParam());
+ const HighbitTexture format = testing::get<1>(GetParam());
+ if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported())
+ return;
+
+ SetSupportHighbitTexture(format);
CreateTestYUVVideoDrawQuad_Striped(
shared_state, media::PIXEL_FORMAT_YV12, false, highbit,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
@@ -1145,9 +1241,16 @@ TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
+ base::FilePath file_path =
+ base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png"));
+ if (format == HighbitTexture::RGBA_8888) {
+ file_path =
+ base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped_rgba.png"));
+ }
EXPECT_TRUE(this->RunPixelTest(
- &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
- FuzzyPixelOffByOneComparator(true)));
+ &pass_list, file_path,
+ // All pixels can be off by two, but any more than that is an error.
+ FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0)));
}
TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) {
@@ -1199,7 +1302,13 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
}
// First argument (test case prefix) is intentionally left empty.
-INSTANTIATE_TEST_CASE_P(, VideoGLRendererPixelHiLoTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+ ,
+ VideoGLRendererPixelHiLoTest,
+ ::testing::Combine(::testing::Bool(),
+ ::testing::Values(HighbitTexture::Y8,
+ HighbitTexture::LUMINANCE_F16,
+ HighbitTexture::RGBA_8888)));
TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
gfx::Rect rect(this->device_viewport_size_);
@@ -1233,11 +1342,13 @@ TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) {
SharedQuadState* shared_state =
CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
+ ResourceFormat y_format = video_resource_updater_->YuvResourceFormat(8);
+
// YUV of (149,43,21) should be green (0,255,0) in RGB.
CreateTestYUVVideoDrawQuad_NV12(
shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(),
- gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), rect, rect,
- resource_provider_.get());
+ y_format, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
+ rect, rect, resource_provider_.get());
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -1267,6 +1378,18 @@ TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
FuzzyPixelOffByOneComparator(true)));
}
+TEST_F(VideoGLRendererPixelTest, TextureQuadEdgeBleed) {
+ // VideoResourceUpdater::CreateForSoftwarePlanes() converts YUV frame to RGBA
+ // texture.
+ DisableOneComponentTextures();
+ RenderPassList pass_list;
+ CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
+ &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_draw_cache.h ('k') | cc/output/shader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698