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

Side by Side Diff: cc/resources/video_resource_updater.cc

Issue 2418173002: Fix HTML5 video blurry (Closed)
Patch Set: add pixeltests 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "cc/resources/video_resource_updater.h" 5 #include "cc/resources/video_resource_updater.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 uint16_t* dst) { 302 uint16_t* dst) {
303 // Source and dest stride can be zero since we're only copying 303 // Source and dest stride can be zero since we're only copying
304 // one row at a time. 304 // one row at a time.
305 int stride = 0; 305 int stride = 0;
306 // Maximum value used in |src|. 306 // Maximum value used in |src|.
307 int max_value = (1 << bits_per_channel) - 1; 307 int max_value = (1 << bits_per_channel) - 1;
308 int rows = 1; 308 int rows = 1;
309 libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows); 309 libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows);
310 } 310 }
311 311
312 ResourceFormat VideoResourceUpdater::YuvResourceFormat(int bits) const {
dshwang 2016/10/18 19:14:36 Move this logic from ResourceProvider because 1. t
313 if (!context_provider_)
314 return LUMINANCE_8;
315
316 const auto caps = context_provider_->ContextCapabilities();
317 if (caps.disable_one_component_textures)
318 return RGBA_8888;
319
320 ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8;
321 if (bits <= 8)
322 return yuv_resource_format;
323
324 if (caps.texture_half_float_linear)
325 return LUMINANCE_F16;
326
327 return yuv_resource_format;
328 }
329
312 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 330 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
313 scoped_refptr<media::VideoFrame> video_frame) { 331 scoped_refptr<media::VideoFrame> video_frame) {
314 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 332 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
315 const media::VideoPixelFormat input_frame_format = video_frame->format(); 333 const media::VideoPixelFormat input_frame_format = video_frame->format();
316 334
317 // TODO(hubbe): Make this a video frame method. 335 // TODO(hubbe): Make this a video frame method.
318 int bits_per_channel = 0; 336 int bits_per_channel = 0;
319 switch (input_frame_format) { 337 switch (input_frame_format) {
320 case media::PIXEL_FORMAT_UNKNOWN: 338 case media::PIXEL_FORMAT_UNKNOWN:
321 NOTREACHED(); 339 NOTREACHED();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 378
361 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 379 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436
362 DCHECK_NE(bits_per_channel, 16); 380 DCHECK_NE(bits_per_channel, 16);
363 381
364 // Only YUV software video frames are supported. 382 // Only YUV software video frames are supported.
365 if (!media::IsYuvPlanar(input_frame_format)) { 383 if (!media::IsYuvPlanar(input_frame_format)) {
366 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); 384 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format);
367 return VideoFrameExternalResources(); 385 return VideoFrameExternalResources();
368 } 386 }
369 387
370 const bool software_compositor = context_provider_ == NULL; 388 const bool software_compositor = context_provider_ == nullptr;
389 bool disable_one_component_textures = true;
390 if (!software_compositor) {
391 const auto caps = context_provider_->ContextCapabilities();
392 disable_one_component_textures = caps.disable_one_component_textures;
393 }
371 394
372 ResourceFormat output_resource_format = 395 ResourceFormat output_resource_format = YuvResourceFormat(bits_per_channel);
373 resource_provider_->YuvResourceFormat(bits_per_channel);
374 396
375 // If GPU compositing is enabled, but the output resource format 397 // If GPU compositing is enabled, but the output resource format
376 // returned by the resource provider is RGBA_8888, then a GPU driver 398 // returned by the resource provider is RGBA_8888, then a GPU driver
377 // bug workaround requires that YUV frames must be converted to RGB 399 // bug workaround requires that YUV frames must be converted to RGB
378 // before texture upload. 400 // before texture upload.
379 bool texture_needs_rgb_conversion = 401 bool texture_needs_rgb_conversion =
380 !software_compositor && 402 !software_compositor && disable_one_component_textures;
381 output_resource_format == ResourceFormat::RGBA_8888;
382 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); 403 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
383 404
384 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB 405 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
385 // conversion here. That involves an extra copy of each frame to a bitmap. 406 // conversion here. That involves an extra copy of each frame to a bitmap.
386 // Obviously, this is suboptimal and should be addressed once ubercompositor 407 // Obviously, this is suboptimal and should be addressed once ubercompositor
387 // starts shaping up. 408 // starts shaping up.
388 if (software_compositor || texture_needs_rgb_conversion) { 409 if (software_compositor || texture_needs_rgb_conversion) {
389 output_resource_format = kRGBResourceFormat; 410 output_resource_format = kRGBResourceFormat;
390 output_plane_count = 1; 411 output_plane_count = 1;
391 bits_per_channel = 8; 412 bits_per_channel = 8;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 // by software. 468 // by software.
448 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); 469 video_renderer_->Copy(video_frame, &canvas, media::Context3D());
449 } else { 470 } else {
450 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( 471 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
451 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); 472 video_frame->coded_size().width(), ResourceFormat::RGBA_8888);
452 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); 473 size_t needed_size = bytes_per_row * video_frame->coded_size().height();
453 if (upload_pixels_.size() < needed_size) 474 if (upload_pixels_.size() < needed_size)
454 upload_pixels_.resize(needed_size); 475 upload_pixels_.resize(needed_size);
455 476
456 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( 477 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
457 video_frame.get(), &upload_pixels_[0], bytes_per_row); 478 video_frame.get(),
479 media::SkCanvasVideoRenderer::ConvertingSize::CODED,
480 &upload_pixels_[0], bytes_per_row);
458 481
459 resource_provider_->CopyToResource(plane_resource.resource_id(), 482 resource_provider_->CopyToResource(plane_resource.resource_id(),
460 &upload_pixels_[0], 483 &upload_pixels_[0],
461 plane_resource.resource_size()); 484 plane_resource.resource_size());
462 } 485 }
463 plane_resource.SetUniqueId(video_frame->unique_id(), 0); 486 plane_resource.SetUniqueId(video_frame->unique_id(), 0);
464 } 487 }
465 488
466 if (software_compositor) { 489 if (software_compositor) {
467 external_resources.software_resources.push_back( 490 external_resources.software_resources.push_back(
468 plane_resource.resource_id()); 491 plane_resource.resource_id());
469 external_resources.software_release_callback = base::Bind( 492 external_resources.software_release_callback = base::Bind(
470 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); 493 &RecycleResource, AsWeakPtr(), plane_resource.resource_id());
471 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; 494 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
472 } else { 495 } else {
473 // VideoResourceUpdater shares a context with the compositor so 496 // VideoResourceUpdater shares a context with the compositor so
474 // a sync token is not required. 497 // a sync token is not required.
475 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), 498 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(),
476 resource_provider_->GetResourceTextureTarget( 499 resource_provider_->GetResourceTextureTarget(
477 plane_resource.resource_id())); 500 plane_resource.resource_id()),
501 plane_resource.resource_size(), false, false);
dshwang 2016/10/18 19:14:36 This hidden bug is covered by VideoGLRendererPixel
478 mailbox.set_color_space(video_frame->ColorSpace()); 502 mailbox.set_color_space(video_frame->ColorSpace());
479 external_resources.mailboxes.push_back(mailbox); 503 external_resources.mailboxes.push_back(mailbox);
480 external_resources.release_callbacks.push_back(base::Bind( 504 external_resources.release_callbacks.push_back(base::Bind(
481 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); 505 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()));
482 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; 506 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
483 } 507 }
484 return external_resources; 508 return external_resources;
485 } 509 }
486 510
487 for (size_t i = 0; i < plane_resources.size(); ++i) { 511 for (size_t i = 0; i < plane_resources.size(); ++i) {
488 PlaneResource& plane_resource = *plane_resources[i]; 512 PlaneResource& plane_resource = *plane_resources[i];
489 // Update each plane's resource id with its content. 513 // Update each plane's resource id with its content.
490 DCHECK_EQ(plane_resource.resource_format(), 514 DCHECK_EQ(plane_resource.resource_format(),
491 resource_provider_->YuvResourceFormat(bits_per_channel)); 515 YuvResourceFormat(bits_per_channel));
492 516
493 if (!plane_resource.Matches(video_frame->unique_id(), i)) { 517 if (!plane_resource.Matches(video_frame->unique_id(), i)) {
494 // TODO(hubbe): Move all conversion (and upload?) code to media/. 518 // TODO(hubbe): Move all conversion (and upload?) code to media/.
495 // We need to transfer data from |video_frame| to the plane resource. 519 // We need to transfer data from |video_frame| to the plane resource.
496 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. 520 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
497 521
498 // The |resource_size_pixels| is the size of the resource we want to 522 // The |resource_size_pixels| is the size of the resource we want to
499 // upload to. 523 // upload to.
500 gfx::Size resource_size_pixels = plane_resource.resource_size(); 524 gfx::Size resource_size_pixels = plane_resource.resource_size();
501 // The |video_stride_bytes| is the width of the video frame we are 525 // The |video_stride_bytes| is the width of the video frame we are
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 if (lost_resource) { 787 if (lost_resource) {
764 resource_it->clear_refs(); 788 resource_it->clear_refs();
765 updater->DeleteResource(resource_it); 789 updater->DeleteResource(resource_it);
766 return; 790 return;
767 } 791 }
768 792
769 resource_it->remove_ref(); 793 resource_it->remove_ref();
770 } 794 }
771 795
772 } // namespace cc 796 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698