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

Side by Side Diff: media/renderers/skcanvas_video_renderer.cc

Issue 2767063002: 16-bit video upload to float: intermediate R16_EXT and copy to float. (Closed)
Patch Set: Rebase. Comments fix. Thanks kbr@. Created 3 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/renderers/skcanvas_video_renderer.h" 5 #include "media/renderers/skcanvas_video_renderer.h"
6 6
7 #include <GLES3/gl3.h> 7 #include <GLES3/gl3.h>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "cc/paint/paint_canvas.h" 12 #include "cc/paint/paint_canvas.h"
13 #include "cc/paint/paint_flags.h" 13 #include "cc/paint/paint_flags.h"
14 #include "cc/paint/paint_image.h" 14 #include "cc/paint/paint_image.h"
15 #include "gpu/GLES2/gl2extchromium.h" 15 #include "gpu/GLES2/gl2extchromium.h"
16 #include "gpu/command_buffer/client/gles2_interface.h" 16 #include "gpu/command_buffer/client/gles2_interface.h"
17 #include "gpu/command_buffer/common/capabilities.h"
17 #include "gpu/command_buffer/common/mailbox_holder.h" 18 #include "gpu/command_buffer/common/mailbox_holder.h"
18 #include "media/base/data_buffer.h" 19 #include "media/base/data_buffer.h"
19 #include "media/base/video_frame.h" 20 #include "media/base/video_frame.h"
20 #include "skia/ext/texture_handle.h" 21 #include "skia/ext/texture_handle.h"
21 #include "third_party/libyuv/include/libyuv.h" 22 #include "third_party/libyuv/include/libyuv.h"
22 #include "third_party/skia/include/core/SkImage.h" 23 #include "third_party/skia/include/core/SkImage.h"
23 #include "third_party/skia/include/core/SkImageGenerator.h" 24 #include "third_party/skia/include/core/SkImageGenerator.h"
24 #include "third_party/skia/include/gpu/GrContext.h" 25 #include "third_party/skia/include/gpu/GrContext.h"
25 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" 26 #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
26 #include "ui/gfx/geometry/rect_f.h" 27 #include "ui/gfx/geometry/rect_f.h"
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 *out_row++ = gray_value; 569 *out_row++ = gray_value;
569 *out_row++ = gray_value; 570 *out_row++ = gray_value;
570 *out_row++ = 1.0f; 571 *out_row++ = 1.0f;
571 } 572 }
572 continue; 573 continue;
573 } else if (format == GL_RED) { 574 } else if (format == GL_RED) {
574 while (row < row_end) 575 while (row < row_end)
575 *out_row++ = *row++ / 65535.f; 576 *out_row++ = *row++ / 65535.f;
576 continue; 577 continue;
577 } 578 }
578 // For other formats, hit NOTREACHED bellow. 579 // For other formats, hit NOTREACHED below.
579 } else if (type == GL_UNSIGNED_BYTE) { 580 } else if (type == GL_UNSIGNED_BYTE) {
580 // We take the upper 8 bits of 16-bit data and convert it as luminance to 581 // We take the upper 8 bits of 16-bit data and convert it as luminance to
581 // ARGB. We loose the precision here, but it is important not to render 582 // ARGB. We loose the precision here, but it is important not to render
582 // Y16 as RG_88. To get the full precision use float textures with WebGL1 583 // Y16 as RG_88. To get the full precision use float textures with WebGL1
583 // and e.g. R16UI or R32F textures with WebGL2. 584 // and e.g. R16UI or R32F textures with WebGL2.
584 DCHECK_EQ(static_cast<unsigned>(GL_RGBA), format); 585 DCHECK_EQ(static_cast<unsigned>(GL_RGBA), format);
585 uint32_t* rgba = reinterpret_cast<uint32_t*>(out_row_head); 586 uint32_t* rgba = reinterpret_cast<uint32_t*>(out_row_head);
586 while (row < row_end) { 587 while (row < row_end) {
587 uint32_t gray_value = *row++ >> 8; 588 uint32_t gray_value = *row++ >> 8;
588 *rgba++ = SkColorSetRGB(gray_value, gray_value, gray_value); 589 *rgba++ = SkColorSetRGB(gray_value, gray_value, gray_value);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 632
632 size_t output_row_bytes = 633 size_t output_row_bytes =
633 frame->visible_rect().width() * output_bytes_per_pixel; 634 frame->visible_rect().width() * output_bytes_per_pixel;
634 *temp_buffer = 635 *temp_buffer =
635 new DataBuffer(output_row_bytes * frame->visible_rect().height()); 636 new DataBuffer(output_row_bytes * frame->visible_rect().height());
636 FlipAndConvertY16(frame, (*temp_buffer)->writable_data(), format, type, 637 FlipAndConvertY16(frame, (*temp_buffer)->writable_data(), format, type,
637 flip_y, output_row_bytes); 638 flip_y, output_row_bytes);
638 return true; 639 return true;
639 } 640 }
640 641
642 // Upload the |frame| data to temporary texture of |temp_format|,
643 // |temp_internalformat| and |temp_type| and then copy intermediate texture
644 // subimage to destination |texture|. The destination |texture| is bound to the
645 // |target| before the call.
646 void TextureSubImageUsingIntermediate(unsigned target,
647 unsigned texture,
648 gpu::gles2::GLES2Interface* gl,
649 VideoFrame* frame,
650 int temp_internalformat,
651 unsigned temp_format,
652 unsigned temp_type,
653 int level,
654 int xoffset,
655 int yoffset,
656 bool flip_y,
657 bool premultiply_alpha) {
658 unsigned temp_texture = 0;
659 gl->GenTextures(1, &temp_texture);
660 gl->BindTexture(target, temp_texture);
661 gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
662 gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
663 gl->TexImage2D(target, 0, temp_internalformat, frame->visible_rect().width(),
664 frame->visible_rect().height(), 0, temp_format, temp_type,
665 frame->visible_data(0));
666 gl->BindTexture(target, texture);
667 gl->CopySubTextureCHROMIUM(temp_texture, 0, target, texture, level, 0, 0,
668 xoffset, yoffset, frame->visible_rect().width(),
669 frame->visible_rect().height(), flip_y,
670 premultiply_alpha, false);
671 gl->DeleteTextures(1, &temp_texture);
672 }
673
641 } // anonymous namespace 674 } // anonymous namespace
642 675
643 // static 676 // static
644 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( 677 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
645 const VideoFrame* video_frame, 678 const VideoFrame* video_frame,
646 void* rgb_pixels, 679 void* rgb_pixels,
647 size_t row_bytes) { 680 size_t row_bytes) {
648 if (!video_frame->IsMappable()) { 681 if (!video_frame->IsMappable()) {
649 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; 682 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats.";
650 return; 683 return;
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 video_frame->UpdateReleaseSyncToken(&client); 953 video_frame->UpdateReleaseSyncToken(&client);
921 } else { 954 } else {
922 CopyVideoFrameSingleTextureToGLTexture( 955 CopyVideoFrameSingleTextureToGLTexture(
923 destination_gl, video_frame.get(), SingleFrameForWebGL, texture, 956 destination_gl, video_frame.get(), SingleFrameForWebGL, texture,
924 internal_format, format, type, premultiply_alpha, flip_y); 957 internal_format, format, type, premultiply_alpha, flip_y);
925 } 958 }
926 959
927 return true; 960 return true;
928 } 961 }
929 962
930 bool SkCanvasVideoRenderer::TexImage2D(unsigned target, 963 bool SkCanvasVideoRenderer::TexImage2D(
931 gpu::gles2::GLES2Interface* gl, 964 unsigned target,
932 VideoFrame* frame, 965 unsigned texture,
933 int level, 966 gpu::gles2::GLES2Interface* gl,
934 int internalformat, 967 const gpu::Capabilities& gpu_capabilities,
935 unsigned format, 968 VideoFrame* frame,
936 unsigned type, 969 int level,
937 bool flip_y, 970 int internalformat,
938 bool premultiply_alpha) { 971 unsigned format,
972 unsigned type,
973 bool flip_y,
974 bool premultiply_alpha) {
939 DCHECK(frame); 975 DCHECK(frame);
940 DCHECK(!frame->HasTextures()); 976 DCHECK(!frame->HasTextures());
941 977
978 // Note: CopyTextureCHROMIUM uses mediump for color computation. Don't use
979 // it if the precision would lead to data loss when converting 16-bit
980 // normalized to float. medium_float.precision > 15 means that the approach
981 // below is not used on Android, where the extension EXT_texture_norm16 is
982 // not widely supported. It is used on Windows, Linux and OSX.
983 // Android support is not required for now because Tango depth camera already
984 // provides floating point data (projected point cloud). See crbug.com/674440.
985 if (gpu_capabilities.texture_norm16 &&
986 gpu_capabilities.fragment_shader_precisions.medium_float.precision > 15 &&
987 target == GL_TEXTURE_2D &&
988 (type == GL_FLOAT || type == GL_UNSIGNED_BYTE)) {
989 // TODO(aleksandar.stojiljkovic): Extend the approach to TexSubImage2D
990 // implementation and other types. See https://crbug.com/624436.
991
992 // Allocate the destination texture.
993 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(),
994 frame->visible_rect().height(), 0, format, type, nullptr);
995 // We use sized internal format GL_R16_EXT instead of unsized GL_RED.
996 // See angleproject:1952
997 TextureSubImageUsingIntermediate(target, texture, gl, frame, GL_R16_EXT,
998 GL_RED, GL_UNSIGNED_SHORT, level, 0, 0,
999 flip_y, premultiply_alpha);
1000 return true;
1001 }
942 scoped_refptr<DataBuffer> temp_buffer; 1002 scoped_refptr<DataBuffer> temp_buffer;
943 if (!TexImageHelper(frame, format, type, flip_y, &temp_buffer)) 1003 if (!TexImageHelper(frame, format, type, flip_y, &temp_buffer))
944 return false; 1004 return false;
945 1005
946 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), 1006 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(),
947 frame->visible_rect().height(), 0, format, type, 1007 frame->visible_rect().height(), 0, format, type,
948 temp_buffer->data()); 1008 temp_buffer->data());
949 return true; 1009 return true;
950 } 1010 }
951 1011
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 last_image_->bounds().contains(visible_rect)) { 1082 last_image_->bounds().contains(visible_rect)) {
1023 last_image_ = last_image_->makeSubset(visible_rect); 1083 last_image_ = last_image_->makeSubset(visible_rect);
1024 } 1084 }
1025 } 1085 }
1026 1086
1027 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { 1087 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() {
1028 return last_image_dimensions_for_testing_; 1088 return last_image_dimensions_for_testing_;
1029 } 1089 }
1030 1090
1031 } // namespace media 1091 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698