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

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

Issue 2763503002: Move HalfFloatMaker to media (Closed)
Patch Set: Added math.h in half_float_maker_unittest.cc for POW undefined error Created 3 years, 9 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
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | cc/resources/video_resource_updater_unittest.cc » ('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>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bit_cast.h" 13 #include "base/bit_cast.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "cc/base/math_util.h" 15 #include "cc/base/math_util.h"
16 #include "cc/output/gl_renderer.h" 16 #include "cc/output/gl_renderer.h"
17 #include "cc/paint/skia_paint_canvas.h" 17 #include "cc/paint/skia_paint_canvas.h"
18 #include "cc/resources/resource_provider.h" 18 #include "cc/resources/resource_provider.h"
19 #include "cc/resources/resource_util.h" 19 #include "cc/resources/resource_util.h"
20 #include "gpu/GLES2/gl2extchromium.h" 20 #include "gpu/GLES2/gl2extchromium.h"
21 #include "gpu/command_buffer/client/gles2_interface.h" 21 #include "gpu/command_buffer/client/gles2_interface.h"
22 #include "media/base/video_frame.h" 22 #include "media/base/video_frame.h"
23 #include "media/renderers/skcanvas_video_renderer.h" 23 #include "media/renderers/skcanvas_video_renderer.h"
24 #include "media/video/half_float_maker.h"
24 #include "third_party/khronos/GLES2/gl2.h" 25 #include "third_party/khronos/GLES2/gl2.h"
25 #include "third_party/khronos/GLES2/gl2ext.h" 26 #include "third_party/khronos/GLES2/gl2ext.h"
26 #include "third_party/libyuv/include/libyuv.h" 27 #include "third_party/libyuv/include/libyuv.h"
27 #include "third_party/skia/include/core/SkCanvas.h" 28 #include "third_party/skia/include/core/SkCanvas.h"
28 #include "ui/gfx/geometry/size_conversions.h" 29 #include "ui/gfx/geometry/size_conversions.h"
29 30
30 namespace cc { 31 namespace cc {
31 32
32 namespace { 33 namespace {
33 34
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 if (software_compositor) 292 if (software_compositor)
292 return coded_size; 293 return coded_size;
293 294
294 int plane_width = media::VideoFrame::Columns( 295 int plane_width = media::VideoFrame::Columns(
295 plane_index, input_frame->format(), coded_size.width()); 296 plane_index, input_frame->format(), coded_size.width());
296 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(), 297 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(),
297 coded_size.height()); 298 coded_size.height());
298 return gfx::Size(plane_width, plane_height); 299 return gfx::Size(plane_width, plane_height);
299 } 300 }
300 301
301 namespace {
302 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the
303 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75).
304 //
305 // Half-floats are evaluated as:
306 // float value = pow(2.0, exponent - 25) * (0x400 + fraction);
307 //
308 // In our case the exponent is 14 (since we or with 0x3800) and
309 // pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and
310 // pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and
311 // [0..0.24951171875] for 9-bit.
312 //
313 // https://en.wikipedia.org/wiki/Half-precision_floating-point_format
314 class HalfFloatMaker_xor : public VideoResourceUpdater::HalfFloatMaker {
315 public:
316 explicit HalfFloatMaker_xor(int bits_per_channel)
317 : bits_per_channel_(bits_per_channel) {}
318 float Offset() const override { return 0.5; }
319 float Multiplier() const override {
320 int max_input_value = (1 << bits_per_channel_) - 1;
321 // 2 << 11 = 2048 would be 1.0 with our exponent.
322 return 2048.0 / max_input_value;
323 }
324 void MakeHalfFloats(const uint16_t* src, size_t num, uint16_t* dst) override {
325 // Micro-benchmarking indicates that the compiler does
326 // a good enough job of optimizing this loop that trying
327 // to manually operate on one uint64 at a time is not
328 // actually helpful.
329 // Note to future optimizers: Benchmark your optimizations!
330 for (size_t i = 0; i < num; i++)
331 dst[i] = src[i] | 0x3800;
332 }
333
334 private:
335 int bits_per_channel_;
336 };
337
338 class HalfFloatMaker_libyuv : public VideoResourceUpdater::HalfFloatMaker {
339 public:
340 explicit HalfFloatMaker_libyuv(int bits_per_channel) {
341 int max_value = (1 << bits_per_channel) - 1;
342 // For less than 15 bits, we can give libyuv a multiplier of
343 // 1.0, which is faster on some platforms. If bits is 16 or larger,
344 // a multiplier of 1.0 would cause overflows. However, a multiplier
345 // of 1/max_value would cause subnormal floats, which perform
346 // very poorly on some platforms.
347 if (bits_per_channel <= 15) {
348 libyuv_multiplier_ = 1.0f;
349 } else {
350 // This multiplier makes sure that we avoid subnormal values.
351 libyuv_multiplier_ = 1.0f / 4096.0f;
352 }
353 resource_multiplier_ = 1.0f / libyuv_multiplier_ / max_value;
354 }
355 float Offset() const override { return 0.0f; }
356 float Multiplier() const override { return resource_multiplier_; }
357 void MakeHalfFloats(const uint16_t* src, size_t num, uint16_t* dst) override {
358 // Source and dest stride can be zero since we're only copying
359 // one row at a time.
360 int stride = 0;
361 int rows = 1;
362 libyuv::HalfFloatPlane(src, stride, dst, stride, libyuv_multiplier_, num,
363 rows);
364 }
365
366 private:
367 float libyuv_multiplier_;
368 float resource_multiplier_;
369 };
370
371 } // namespace
372
373 std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>
374 VideoResourceUpdater::NewHalfFloatMaker(int bits_per_channel) {
375 if (bits_per_channel < 11) {
376 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>(
377 new HalfFloatMaker_xor(bits_per_channel));
378 } else {
379 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>(
380 new HalfFloatMaker_libyuv(bits_per_channel));
381 }
382 }
383
384 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 302 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
385 scoped_refptr<media::VideoFrame> video_frame) { 303 scoped_refptr<media::VideoFrame> video_frame) {
386 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 304 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
387 const media::VideoPixelFormat input_frame_format = video_frame->format(); 305 const media::VideoPixelFormat input_frame_format = video_frame->format();
388 306
389 int bits_per_channel = video_frame->BitsPerChannel(input_frame_format); 307 int bits_per_channel = video_frame->BitsPerChannel(input_frame_format);
390 308
391 // Only YUV and Y16 software video frames are supported. 309 // Only YUV and Y16 software video frames are supported.
392 DCHECK(media::IsYuvPlanar(input_frame_format) || 310 DCHECK(media::IsYuvPlanar(input_frame_format) ||
393 input_frame_format == media::PIXEL_FORMAT_Y16); 311 input_frame_format == media::PIXEL_FORMAT_Y16);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 plane_resource.resource_id())); 429 plane_resource.resource_id()));
512 mailbox.set_color_space(output_color_space); 430 mailbox.set_color_space(output_color_space);
513 external_resources.mailboxes.push_back(mailbox); 431 external_resources.mailboxes.push_back(mailbox);
514 external_resources.release_callbacks.push_back(base::Bind( 432 external_resources.release_callbacks.push_back(base::Bind(
515 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); 433 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()));
516 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; 434 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
517 } 435 }
518 return external_resources; 436 return external_resources;
519 } 437 }
520 438
521 std::unique_ptr<HalfFloatMaker> half_float_maker; 439 std::unique_ptr<media::HalfFloatMaker> half_float_maker;
522 if (resource_provider_->YuvResourceFormat(bits_per_channel) == 440 if (resource_provider_->YuvResourceFormat(bits_per_channel) ==
523 LUMINANCE_F16) { 441 LUMINANCE_F16) {
524 half_float_maker = NewHalfFloatMaker(bits_per_channel); 442 half_float_maker =
443 media::HalfFloatMaker::NewHalfFloatMaker(bits_per_channel);
525 external_resources.offset = half_float_maker->Offset(); 444 external_resources.offset = half_float_maker->Offset();
526 external_resources.multiplier = half_float_maker->Multiplier(); 445 external_resources.multiplier = half_float_maker->Multiplier();
527 } 446 }
528 447
529 for (size_t i = 0; i < plane_resources.size(); ++i) { 448 for (size_t i = 0; i < plane_resources.size(); ++i) {
530 PlaneResource& plane_resource = *plane_resources[i]; 449 PlaneResource& plane_resource = *plane_resources[i];
531 // Update each plane's resource id with its content. 450 // Update each plane's resource id with its content.
532 DCHECK_EQ(plane_resource.resource_format(), 451 DCHECK_EQ(plane_resource.resource_format(),
533 resource_provider_->YuvResourceFormat(bits_per_channel)); 452 resource_provider_->YuvResourceFormat(bits_per_channel));
534 453
535 if (!plane_resource.Matches(video_frame->unique_id(), i)) { 454 if (!plane_resource.Matches(video_frame->unique_id(), i)) {
536 // TODO(hubbe): Move all conversion (and upload?) code to media/. 455 // TODO(hubbe): Move upload code to media/.
537 // We need to transfer data from |video_frame| to the plane resource. 456 // We need to transfer data from |video_frame| to the plane resource.
538 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. 457 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
539 458
540 // The |resource_size_pixels| is the size of the resource we want to 459 // The |resource_size_pixels| is the size of the resource we want to
541 // upload to. 460 // upload to.
542 gfx::Size resource_size_pixels = plane_resource.resource_size(); 461 gfx::Size resource_size_pixels = plane_resource.resource_size();
543 // The |video_stride_bytes| is the width of the video frame we are 462 // The |video_stride_bytes| is the width of the video frame we are
544 // uploading (including non-frame data to fill in the stride). 463 // uploading (including non-frame data to fill in the stride).
545 int video_stride_bytes = video_frame->stride(i); 464 int video_stride_bytes = video_frame->stride(i);
546 465
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 if (lost_resource) { 695 if (lost_resource) {
777 resource_it->clear_refs(); 696 resource_it->clear_refs();
778 updater->DeleteResource(resource_it); 697 updater->DeleteResource(resource_it);
779 return; 698 return;
780 } 699 }
781 700
782 resource_it->remove_ref(); 701 resource_it->remove_ref();
783 } 702 }
784 703
785 } // namespace cc 704 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | cc/resources/video_resource_updater_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698