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

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

Issue 2461423002: Reland "Fix HTML5 video blurry" (Closed)
Patch Set: add TODO comment 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(
383 int bits,
384 media::VideoPixelFormat format) const {
385 if (!context_provider_)
386 return RGBA_8888;
387
388 if (format == media::PIXEL_FORMAT_Y16) {
389 // Unable to display directly as yuv planes so convert it to RGBA for
390 // compositing.
391 return RGBA_8888;
392 }
393
394 const auto caps = context_provider_->ContextCapabilities();
395 if (caps.disable_one_component_textures)
396 return RGBA_8888;
397
398 ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8;
399 if (bits <= 8)
400 return yuv_resource_format;
401
402 if (caps.texture_half_float_linear)
403 return LUMINANCE_F16;
404
405 return yuv_resource_format;
406 }
407
382 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 408 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
383 scoped_refptr<media::VideoFrame> video_frame) { 409 scoped_refptr<media::VideoFrame> video_frame) {
384 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 410 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
385 const media::VideoPixelFormat input_frame_format = video_frame->format(); 411 const media::VideoPixelFormat input_frame_format = video_frame->format();
386 412
387 // TODO(hubbe): Make this a video frame method. 413 // TODO(hubbe): Make this a video frame method.
388 int bits_per_channel = 0; 414 int bits_per_channel = 0;
389 switch (input_frame_format) { 415 switch (input_frame_format) {
390 case media::PIXEL_FORMAT_UNKNOWN: 416 case media::PIXEL_FORMAT_UNKNOWN:
391 NOTREACHED(); 417 NOTREACHED();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 break; 451 break;
426 case media::PIXEL_FORMAT_Y16: 452 case media::PIXEL_FORMAT_Y16:
427 bits_per_channel = 16; 453 bits_per_channel = 16;
428 break; 454 break;
429 } 455 }
430 456
431 // Only YUV and Y16 software video frames are supported. 457 // Only YUV and Y16 software video frames are supported.
432 DCHECK(media::IsYuvPlanar(input_frame_format) || 458 DCHECK(media::IsYuvPlanar(input_frame_format) ||
433 input_frame_format == media::PIXEL_FORMAT_Y16); 459 input_frame_format == media::PIXEL_FORMAT_Y16);
434 460
435 const bool software_compositor = context_provider_ == NULL; 461 const bool software_compositor = context_provider_ == nullptr;
462 bool disable_one_component_textures = true;
463 if (!software_compositor) {
464 const auto caps = context_provider_->ContextCapabilities();
465 disable_one_component_textures = caps.disable_one_component_textures;
466 }
436 467
437 ResourceFormat output_resource_format; 468 ResourceFormat output_resource_format =
438 if (input_frame_format == media::PIXEL_FORMAT_Y16) { 469 YuvResourceFormat(bits_per_channel, input_frame_format);
439 // Unable to display directly as yuv planes so convert it to RGBA for
440 // compositing.
441 output_resource_format = RGBA_8888;
442 } else {
443 // Can be composited directly from yuv planes.
444 output_resource_format =
445 resource_provider_->YuvResourceFormat(bits_per_channel);
446 }
447 470
448 // If GPU compositing is enabled, but the output resource format 471 // If GPU compositing is enabled, but the output resource format
449 // returned by the resource provider is RGBA_8888, then a GPU driver 472 // returned by the resource provider is RGBA_8888, then a GPU driver
450 // bug workaround requires that YUV frames must be converted to RGB 473 // bug workaround requires that YUV frames must be converted to RGB
451 // before texture upload. 474 // before texture upload.
452 bool texture_needs_rgb_conversion = 475 bool texture_needs_rgb_conversion =
453 !software_compositor && 476 (!software_compositor && disable_one_component_textures) ||
454 output_resource_format == ResourceFormat::RGBA_8888; 477 input_frame_format == media::PIXEL_FORMAT_Y16;
455 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); 478 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
456 479
457 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB 480 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
458 // conversion here. That involves an extra copy of each frame to a bitmap. 481 // conversion here. That involves an extra copy of each frame to a bitmap.
459 // Obviously, this is suboptimal and should be addressed once ubercompositor 482 // Obviously, this is suboptimal and should be addressed once ubercompositor
460 // starts shaping up. 483 // starts shaping up.
461 if (software_compositor || texture_needs_rgb_conversion) { 484 if (software_compositor || texture_needs_rgb_conversion) {
462 output_resource_format = kRGBResourceFormat; 485 DCHECK_EQ(output_resource_format, kRGBResourceFormat);
463 output_plane_count = 1; 486 output_plane_count = 1;
464 bits_per_channel = 8; 487 bits_per_channel = 8;
465 } 488 }
466 489
467 // Drop recycled resources that are the wrong format. 490 // Drop recycled resources that are the wrong format.
468 for (auto it = all_resources_.begin(); it != all_resources_.end();) { 491 for (auto it = all_resources_.begin(); it != all_resources_.end();) {
469 if (!it->has_refs() && it->resource_format() != output_resource_format) 492 if (!it->has_refs() && it->resource_format() != output_resource_format)
470 DeleteResource(it++); 493 DeleteResource(it++);
471 else 494 else
472 ++it; 495 ++it;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // by software. 543 // by software.
521 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); 544 video_renderer_->Copy(video_frame, &canvas, media::Context3D());
522 } else { 545 } else {
523 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( 546 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
524 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); 547 video_frame->coded_size().width(), ResourceFormat::RGBA_8888);
525 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); 548 size_t needed_size = bytes_per_row * video_frame->coded_size().height();
526 if (upload_pixels_.size() < needed_size) 549 if (upload_pixels_.size() < needed_size)
527 upload_pixels_.resize(needed_size); 550 upload_pixels_.resize(needed_size);
528 551
529 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( 552 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
530 video_frame.get(), &upload_pixels_[0], bytes_per_row); 553 video_frame.get(),
554 media::SkCanvasVideoRenderer::ConvertingSize::CODED,
555 &upload_pixels_[0], bytes_per_row);
531 556
532 resource_provider_->CopyToResource(plane_resource.resource_id(), 557 resource_provider_->CopyToResource(plane_resource.resource_id(),
533 &upload_pixels_[0], 558 &upload_pixels_[0],
534 plane_resource.resource_size()); 559 plane_resource.resource_size());
535 } 560 }
536 plane_resource.SetUniqueId(video_frame->unique_id(), 0); 561 plane_resource.SetUniqueId(video_frame->unique_id(), 0);
537 } 562 }
538 563
539 if (software_compositor) { 564 if (software_compositor) {
540 external_resources.software_resources.push_back( 565 external_resources.software_resources.push_back(
541 plane_resource.resource_id()); 566 plane_resource.resource_id());
542 external_resources.software_release_callback = base::Bind( 567 external_resources.software_release_callback = base::Bind(
543 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); 568 &RecycleResource, AsWeakPtr(), plane_resource.resource_id());
544 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; 569 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
545 } else { 570 } else {
546 // VideoResourceUpdater shares a context with the compositor so 571 // VideoResourceUpdater shares a context with the compositor so
547 // a sync token is not required. 572 // a sync token is not required.
548 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), 573 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(),
549 resource_provider_->GetResourceTextureTarget( 574 resource_provider_->GetResourceTextureTarget(
550 plane_resource.resource_id())); 575 plane_resource.resource_id()),
576 plane_resource.resource_size(), false, false);
551 mailbox.set_color_space(video_frame->ColorSpace()); 577 mailbox.set_color_space(video_frame->ColorSpace());
552 external_resources.mailboxes.push_back(mailbox); 578 external_resources.mailboxes.push_back(mailbox);
553 external_resources.release_callbacks.push_back(base::Bind( 579 external_resources.release_callbacks.push_back(base::Bind(
554 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); 580 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()));
555 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; 581 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
556 } 582 }
557 return external_resources; 583 return external_resources;
558 } 584 }
559 585
560 std::unique_ptr<HalfFloatMaker> half_float_maker; 586 std::unique_ptr<HalfFloatMaker> half_float_maker;
561 if (resource_provider_->YuvResourceFormat(bits_per_channel) == 587 if (YuvResourceFormat(bits_per_channel, input_frame_format) ==
562 LUMINANCE_F16) { 588 LUMINANCE_F16) {
563 half_float_maker = NewHalfFloatMaker(bits_per_channel); 589 half_float_maker = NewHalfFloatMaker(bits_per_channel);
564 external_resources.offset = half_float_maker->Offset(); 590 external_resources.offset = half_float_maker->Offset();
565 external_resources.multiplier = half_float_maker->Multiplier(); 591 external_resources.multiplier = half_float_maker->Multiplier();
566 } 592 }
567 593
568 for (size_t i = 0; i < plane_resources.size(); ++i) { 594 for (size_t i = 0; i < plane_resources.size(); ++i) {
569 PlaneResource& plane_resource = *plane_resources[i]; 595 PlaneResource& plane_resource = *plane_resources[i];
570 // Update each plane's resource id with its content. 596 // Update each plane's resource id with its content.
571 DCHECK_EQ(plane_resource.resource_format(), 597 DCHECK_EQ(plane_resource.resource_format(),
572 resource_provider_->YuvResourceFormat(bits_per_channel)); 598 YuvResourceFormat(bits_per_channel, input_frame_format));
573 599
574 if (!plane_resource.Matches(video_frame->unique_id(), i)) { 600 if (!plane_resource.Matches(video_frame->unique_id(), i)) {
575 // TODO(hubbe): Move all conversion (and upload?) code to media/. 601 // TODO(hubbe): Move all conversion (and upload?) code to media/.
576 // We need to transfer data from |video_frame| to the plane resource. 602 // We need to transfer data from |video_frame| to the plane resource.
577 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. 603 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
578 604
579 // The |resource_size_pixels| is the size of the resource we want to 605 // The |resource_size_pixels| is the size of the resource we want to
580 // upload to. 606 // upload to.
581 gfx::Size resource_size_pixels = plane_resource.resource_size(); 607 gfx::Size resource_size_pixels = plane_resource.resource_size();
582 // The |video_stride_bytes| is the width of the video frame we are 608 // 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
804 if (lost_resource) { 830 if (lost_resource) {
805 resource_it->clear_refs(); 831 resource_it->clear_refs();
806 updater->DeleteResource(resource_it); 832 updater->DeleteResource(resource_it);
807 return; 833 return;
808 } 834 }
809 835
810 resource_it->remove_ref(); 836 resource_it->remove_ref();
811 } 837 }
812 838
813 } // namespace cc 839 } // 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