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

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

Issue 2418173002: Fix HTML5 video blurry (Closed)
Patch Set: fix nits Created 4 years, 1 month 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/resources/video_resource_updater.h ('k') | cc/test/data/yuv_stripes.png » ('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 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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 VideoResourceUpdater::NewHalfFloatMaker(int bits_per_channel) { 372 VideoResourceUpdater::NewHalfFloatMaker(int bits_per_channel) {
373 if (bits_per_channel < 11) { 373 if (bits_per_channel < 11) {
374 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( 374 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>(
375 new HalfFloatMaker_xor(bits_per_channel)); 375 new HalfFloatMaker_xor(bits_per_channel));
376 } else { 376 } else {
377 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( 377 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>(
378 new HalfFloatMaker_libyuv(bits_per_channel)); 378 new HalfFloatMaker_libyuv(bits_per_channel));
379 } 379 }
380 } 380 }
381 381
382 ResourceFormat VideoResourceUpdater::YuvResourceFormat(int bits) const {
383 if (!context_provider_)
384 return LUMINANCE_8;
385
386 const auto caps = context_provider_->ContextCapabilities();
387 if (caps.disable_one_component_textures)
388 return RGBA_8888;
389
390 ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8;
391 if (bits <= 8)
392 return yuv_resource_format;
393
394 if (caps.texture_half_float_linear)
395 return LUMINANCE_F16;
396
397 return yuv_resource_format;
398 }
399
382 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 400 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
383 scoped_refptr<media::VideoFrame> video_frame) { 401 scoped_refptr<media::VideoFrame> video_frame) {
384 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 402 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
385 const media::VideoPixelFormat input_frame_format = video_frame->format(); 403 const media::VideoPixelFormat input_frame_format = video_frame->format();
386 404
387 // TODO(hubbe): Make this a video frame method. 405 // TODO(hubbe): Make this a video frame method.
388 int bits_per_channel = 0; 406 int bits_per_channel = 0;
389 switch (input_frame_format) { 407 switch (input_frame_format) {
390 case media::PIXEL_FORMAT_UNKNOWN: 408 case media::PIXEL_FORMAT_UNKNOWN:
391 NOTREACHED(); 409 NOTREACHED();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 448
431 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 449 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436
432 DCHECK_NE(bits_per_channel, 16); 450 DCHECK_NE(bits_per_channel, 16);
433 451
434 // Only YUV software video frames are supported. 452 // Only YUV software video frames are supported.
435 if (!media::IsYuvPlanar(input_frame_format)) { 453 if (!media::IsYuvPlanar(input_frame_format)) {
436 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); 454 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format);
437 return VideoFrameExternalResources(); 455 return VideoFrameExternalResources();
438 } 456 }
439 457
440 const bool software_compositor = context_provider_ == NULL; 458 const bool software_compositor = context_provider_ == nullptr;
459 bool disable_one_component_textures = true;
460 if (!software_compositor) {
461 const auto caps = context_provider_->ContextCapabilities();
462 disable_one_component_textures = caps.disable_one_component_textures;
463 }
441 464
442 ResourceFormat output_resource_format = 465 ResourceFormat output_resource_format = YuvResourceFormat(bits_per_channel);
443 resource_provider_->YuvResourceFormat(bits_per_channel);
444 466
445 // If GPU compositing is enabled, but the output resource format 467 // If GPU compositing is enabled, but the output resource format
446 // returned by the resource provider is RGBA_8888, then a GPU driver 468 // returned by the resource provider is RGBA_8888, then a GPU driver
447 // bug workaround requires that YUV frames must be converted to RGB 469 // bug workaround requires that YUV frames must be converted to RGB
448 // before texture upload. 470 // before texture upload.
449 bool texture_needs_rgb_conversion = 471 bool texture_needs_rgb_conversion =
450 !software_compositor && 472 !software_compositor && disable_one_component_textures;
451 output_resource_format == ResourceFormat::RGBA_8888;
452 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); 473 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
453 474
454 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB 475 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
455 // conversion here. That involves an extra copy of each frame to a bitmap. 476 // conversion here. That involves an extra copy of each frame to a bitmap.
456 // Obviously, this is suboptimal and should be addressed once ubercompositor 477 // Obviously, this is suboptimal and should be addressed once ubercompositor
457 // starts shaping up. 478 // starts shaping up.
458 if (software_compositor || texture_needs_rgb_conversion) { 479 if (software_compositor || texture_needs_rgb_conversion) {
459 output_resource_format = kRGBResourceFormat; 480 output_resource_format = kRGBResourceFormat;
460 output_plane_count = 1; 481 output_plane_count = 1;
461 bits_per_channel = 8; 482 bits_per_channel = 8;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 // by software. 538 // by software.
518 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); 539 video_renderer_->Copy(video_frame, &canvas, media::Context3D());
519 } else { 540 } else {
520 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( 541 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
521 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); 542 video_frame->coded_size().width(), ResourceFormat::RGBA_8888);
522 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); 543 size_t needed_size = bytes_per_row * video_frame->coded_size().height();
523 if (upload_pixels_.size() < needed_size) 544 if (upload_pixels_.size() < needed_size)
524 upload_pixels_.resize(needed_size); 545 upload_pixels_.resize(needed_size);
525 546
526 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( 547 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
527 video_frame.get(), &upload_pixels_[0], bytes_per_row); 548 video_frame.get(),
549 media::SkCanvasVideoRenderer::ConvertingSize::CODED,
550 &upload_pixels_[0], bytes_per_row);
528 551
529 resource_provider_->CopyToResource(plane_resource.resource_id(), 552 resource_provider_->CopyToResource(plane_resource.resource_id(),
530 &upload_pixels_[0], 553 &upload_pixels_[0],
531 plane_resource.resource_size()); 554 plane_resource.resource_size());
532 } 555 }
533 plane_resource.SetUniqueId(video_frame->unique_id(), 0); 556 plane_resource.SetUniqueId(video_frame->unique_id(), 0);
534 } 557 }
535 558
536 if (software_compositor) { 559 if (software_compositor) {
537 external_resources.software_resources.push_back( 560 external_resources.software_resources.push_back(
538 plane_resource.resource_id()); 561 plane_resource.resource_id());
539 external_resources.software_release_callback = base::Bind( 562 external_resources.software_release_callback = base::Bind(
540 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); 563 &RecycleResource, AsWeakPtr(), plane_resource.resource_id());
541 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; 564 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
542 } else { 565 } else {
543 // VideoResourceUpdater shares a context with the compositor so 566 // VideoResourceUpdater shares a context with the compositor so
544 // a sync token is not required. 567 // a sync token is not required.
545 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), 568 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(),
546 resource_provider_->GetResourceTextureTarget( 569 resource_provider_->GetResourceTextureTarget(
547 plane_resource.resource_id())); 570 plane_resource.resource_id()),
571 plane_resource.resource_size(), false, false);
548 mailbox.set_color_space(video_frame->ColorSpace()); 572 mailbox.set_color_space(video_frame->ColorSpace());
549 external_resources.mailboxes.push_back(mailbox); 573 external_resources.mailboxes.push_back(mailbox);
550 external_resources.release_callbacks.push_back(base::Bind( 574 external_resources.release_callbacks.push_back(base::Bind(
551 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); 575 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()));
552 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; 576 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
553 } 577 }
554 return external_resources; 578 return external_resources;
555 } 579 }
556 580
557 std::unique_ptr<HalfFloatMaker> half_float_maker; 581 std::unique_ptr<HalfFloatMaker> half_float_maker;
558 if (resource_provider_->YuvResourceFormat(bits_per_channel) == 582 if (YuvResourceFormat(bits_per_channel) == LUMINANCE_F16) {
559 LUMINANCE_F16) {
560 half_float_maker = NewHalfFloatMaker(bits_per_channel); 583 half_float_maker = NewHalfFloatMaker(bits_per_channel);
561 external_resources.offset = half_float_maker->Offset(); 584 external_resources.offset = half_float_maker->Offset();
562 external_resources.multiplier = half_float_maker->Multiplier(); 585 external_resources.multiplier = half_float_maker->Multiplier();
563 } 586 }
564 587
565 for (size_t i = 0; i < plane_resources.size(); ++i) { 588 for (size_t i = 0; i < plane_resources.size(); ++i) {
566 PlaneResource& plane_resource = *plane_resources[i]; 589 PlaneResource& plane_resource = *plane_resources[i];
567 // Update each plane's resource id with its content. 590 // Update each plane's resource id with its content.
568 DCHECK_EQ(plane_resource.resource_format(), 591 DCHECK_EQ(plane_resource.resource_format(),
569 resource_provider_->YuvResourceFormat(bits_per_channel)); 592 YuvResourceFormat(bits_per_channel));
570 593
571 if (!plane_resource.Matches(video_frame->unique_id(), i)) { 594 if (!plane_resource.Matches(video_frame->unique_id(), i)) {
572 // TODO(hubbe): Move all conversion (and upload?) code to media/. 595 // TODO(hubbe): Move all conversion (and upload?) code to media/.
573 // We need to transfer data from |video_frame| to the plane resource. 596 // We need to transfer data from |video_frame| to the plane resource.
574 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. 597 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
575 598
576 // The |resource_size_pixels| is the size of the resource we want to 599 // The |resource_size_pixels| is the size of the resource we want to
577 // upload to. 600 // upload to.
578 gfx::Size resource_size_pixels = plane_resource.resource_size(); 601 gfx::Size resource_size_pixels = plane_resource.resource_size();
579 // The |video_stride_bytes| is the width of the video frame we are 602 // The |video_stride_bytes| is the width of the video frame we are
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 if (lost_resource) { 824 if (lost_resource) {
802 resource_it->clear_refs(); 825 resource_it->clear_refs();
803 updater->DeleteResource(resource_it); 826 updater->DeleteResource(resource_it);
804 return; 827 return;
805 } 828 }
806 829
807 resource_it->remove_ref(); 830 resource_it->remove_ref();
808 } 831 }
809 832
810 } // namespace cc 833 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | cc/test/data/yuv_stripes.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698