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

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

Issue 2763503002: Move HalfFloatMaker to media (Closed)
Patch Set: Moved HalffloatMaker and its implementation from cc to media 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
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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 if (software_compositor) 291 if (software_compositor)
292 return coded_size; 292 return coded_size;
293 293
294 int plane_width = media::VideoFrame::Columns( 294 int plane_width = media::VideoFrame::Columns(
295 plane_index, input_frame->format(), coded_size.width()); 295 plane_index, input_frame->format(), coded_size.width());
296 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(), 296 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(),
297 coded_size.height()); 297 coded_size.height());
298 return gfx::Size(plane_width, plane_height); 298 return gfx::Size(plane_width, plane_height);
299 } 299 }
300 300
301 namespace { 301 std::unique_ptr<media::HalfFloatMaker> VideoResourceUpdater::NewHalfFloatMaker(
hubbe 2017/03/22 17:48:22 Move this function to media
Uzair 2017/03/23 07:13:30 Done.
302 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the 302 int bits_per_channel) {
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) { 303 if (bits_per_channel < 11) {
376 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( 304 return std::unique_ptr<media::HalfFloatMaker>(
377 new HalfFloatMaker_xor(bits_per_channel)); 305 new media::HalfFloatMaker_xor(bits_per_channel));
378 } else { 306 } else {
379 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( 307 return std::unique_ptr<media::HalfFloatMaker>(
380 new HalfFloatMaker_libyuv(bits_per_channel)); 308 new media::HalfFloatMaker_libyuv(bits_per_channel));
381 } 309 }
382 } 310 }
383 311
384 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 312 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
385 scoped_refptr<media::VideoFrame> video_frame) { 313 scoped_refptr<media::VideoFrame> video_frame) {
386 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 314 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
387 const media::VideoPixelFormat input_frame_format = video_frame->format(); 315 const media::VideoPixelFormat input_frame_format = video_frame->format();
388 316
389 int bits_per_channel = video_frame->BitsPerChannel(input_frame_format); 317 int bits_per_channel = video_frame->BitsPerChannel(input_frame_format);
390 318
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 plane_resource.resource_id())); 439 plane_resource.resource_id()));
512 mailbox.set_color_space(output_color_space); 440 mailbox.set_color_space(output_color_space);
513 external_resources.mailboxes.push_back(mailbox); 441 external_resources.mailboxes.push_back(mailbox);
514 external_resources.release_callbacks.push_back(base::Bind( 442 external_resources.release_callbacks.push_back(base::Bind(
515 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); 443 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()));
516 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; 444 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
517 } 445 }
518 return external_resources; 446 return external_resources;
519 } 447 }
520 448
521 std::unique_ptr<HalfFloatMaker> half_float_maker; 449 std::unique_ptr<media::HalfFloatMaker> half_float_maker;
522 if (resource_provider_->YuvResourceFormat(bits_per_channel) == 450 if (resource_provider_->YuvResourceFormat(bits_per_channel) ==
523 LUMINANCE_F16) { 451 LUMINANCE_F16) {
524 half_float_maker = NewHalfFloatMaker(bits_per_channel); 452 half_float_maker = NewHalfFloatMaker(bits_per_channel);
525 external_resources.offset = half_float_maker->Offset(); 453 external_resources.offset = half_float_maker->Offset();
526 external_resources.multiplier = half_float_maker->Multiplier(); 454 external_resources.multiplier = half_float_maker->Multiplier();
527 } 455 }
528 456
529 for (size_t i = 0; i < plane_resources.size(); ++i) { 457 for (size_t i = 0; i < plane_resources.size(); ++i) {
530 PlaneResource& plane_resource = *plane_resources[i]; 458 PlaneResource& plane_resource = *plane_resources[i];
531 // Update each plane's resource id with its content. 459 // Update each plane's resource id with its content.
532 DCHECK_EQ(plane_resource.resource_format(), 460 DCHECK_EQ(plane_resource.resource_format(),
533 resource_provider_->YuvResourceFormat(bits_per_channel)); 461 resource_provider_->YuvResourceFormat(bits_per_channel));
534 462
535 if (!plane_resource.Matches(video_frame->unique_id(), i)) { 463 if (!plane_resource.Matches(video_frame->unique_id(), i)) {
536 // TODO(hubbe): Move all conversion (and upload?) code to media/. 464 // TODO(hubbe): Move all conversion (and upload?) code to media/.
hubbe 2017/03/22 17:48:22 Update this TODO
Uzair 2017/03/23 07:13:30 Done.
537 // We need to transfer data from |video_frame| to the plane resource. 465 // We need to transfer data from |video_frame| to the plane resource.
538 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. 466 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
539 467
540 // The |resource_size_pixels| is the size of the resource we want to 468 // The |resource_size_pixels| is the size of the resource we want to
541 // upload to. 469 // upload to.
542 gfx::Size resource_size_pixels = plane_resource.resource_size(); 470 gfx::Size resource_size_pixels = plane_resource.resource_size();
543 // The |video_stride_bytes| is the width of the video frame we are 471 // The |video_stride_bytes| is the width of the video frame we are
544 // uploading (including non-frame data to fill in the stride). 472 // uploading (including non-frame data to fill in the stride).
545 int video_stride_bytes = video_frame->stride(i); 473 int video_stride_bytes = video_frame->stride(i);
546 474
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 if (lost_resource) { 704 if (lost_resource) {
777 resource_it->clear_refs(); 705 resource_it->clear_refs();
778 updater->DeleteResource(resource_it); 706 updater->DeleteResource(resource_it);
779 return; 707 return;
780 } 708 }
781 709
782 resource_it->remove_ref(); 710 resource_it->remove_ref();
783 } 711 }
784 712
785 } // namespace cc 713 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698