Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "gpu/GLES2/gl2extchromium.h" | 9 #include "gpu/GLES2/gl2extchromium.h" |
| 10 #include "gpu/command_buffer/client/gles2_interface.h" | 10 #include "gpu/command_buffer/client/gles2_interface.h" |
| 11 #include "gpu/command_buffer/common/mailbox_holder.h" | 11 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 12 #include "media/base/video_frame.h" | 12 #include "media/base/video_frame.h" |
| 13 #include "media/base/yuv_convert.h" | 13 #include "media/base/yuv_convert.h" |
| 14 #include "skia/ext/refptr.h" | 14 #include "skia/ext/refptr.h" |
| 15 #include "third_party/libyuv/include/libyuv.h" | 15 #include "third_party/libyuv/include/libyuv.h" |
| 16 #include "third_party/skia/include/core/SkCanvas.h" | 16 #include "third_party/skia/include/core/SkCanvas.h" |
| 17 #include "third_party/skia/include/core/SkImage.h" | 17 #include "third_party/skia/include/core/SkImage.h" |
| 18 #include "third_party/skia/include/core/SkImageGenerator.h" | 18 #include "third_party/skia/include/core/SkImageGenerator.h" |
| 19 #include "third_party/skia/include/gpu/GrContext.h" | 19 #include "third_party/skia/include/gpu/GrContext.h" |
| 20 #include "third_party/skia/include/gpu/GrPaint.h" | 20 #include "third_party/skia/include/gpu/GrPaint.h" |
| 21 #include "third_party/skia/include/gpu/GrTexture.h" | 21 #include "third_party/skia/include/gpu/GrTexture.h" |
| 22 #include "third_party/skia/include/gpu/GrTextureProvider.h" | 22 #include "third_party/skia/include/gpu/GrTextureProvider.h" |
| 23 #include "third_party/skia/include/gpu/SkGr.h" | 23 #include "third_party/skia/include/gpu/SkGr.h" |
| 24 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" | |
| 24 #include "ui/gfx/geometry/rect_f.h" | 25 #include "ui/gfx/geometry/rect_f.h" |
| 25 #include "ui/gfx/skia_util.h" | 26 #include "ui/gfx/skia_util.h" |
| 26 | 27 |
| 27 // Skia internal format depends on a platform. On Android it is ABGR, on others | 28 // Skia internal format depends on a platform. On Android it is ABGR, on others |
| 28 // it is ARGB. | 29 // it is ARGB. |
| 29 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ | 30 #if SK_B32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_R32_SHIFT == 16 && \ |
| 30 SK_A32_SHIFT == 24 | 31 SK_A32_SHIFT == 24 |
| 31 #define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB | 32 #define LIBYUV_I420_TO_ARGB libyuv::I420ToARGB |
| 32 #define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB | 33 #define LIBYUV_I422_TO_ARGB libyuv::I422ToARGB |
| 33 #define LIBYUV_I444_TO_ARGB libyuv::I444ToARGB | 34 #define LIBYUV_I444_TO_ARGB libyuv::I444ToARGB |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 DCHECK(video_frame->HasTextures()); | 88 DCHECK(video_frame->HasTextures()); |
| 88 DCHECK_EQ(media::PIXEL_FORMAT_I420, video_frame->format()); | 89 DCHECK_EQ(media::PIXEL_FORMAT_I420, video_frame->format()); |
| 89 DCHECK_EQ(3u, media::VideoFrame::NumPlanes(video_frame->format())); | 90 DCHECK_EQ(3u, media::VideoFrame::NumPlanes(video_frame->format())); |
| 90 | 91 |
| 91 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 92 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 92 DCHECK(gl); | 93 DCHECK(gl); |
| 93 gfx::Size ya_tex_size = video_frame->coded_size(); | 94 gfx::Size ya_tex_size = video_frame->coded_size(); |
| 94 gfx::Size uv_tex_size((ya_tex_size.width() + 1) / 2, | 95 gfx::Size uv_tex_size((ya_tex_size.width() + 1) / 2, |
| 95 (ya_tex_size.height() + 1) / 2); | 96 (ya_tex_size.height() + 1) / 2); |
| 96 | 97 |
| 97 unsigned source_textures[3] = {0}; | 98 GrGLTextureInfo source_textures[] = {{0, 0}, {0, 0}, {0, 0}}; |
| 98 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format()); | 99 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format()); |
| 99 ++i) { | 100 ++i) { |
| 100 // Get the texture from the mailbox and wrap it in a GrTexture. | 101 // Get the texture from the mailbox and wrap it in a GrTexture. |
| 101 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); | 102 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); |
| 102 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 103 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
| 103 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES || | 104 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES || |
| 104 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB); | 105 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB); |
| 105 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 106 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 106 source_textures[i] = gl->CreateAndConsumeTextureCHROMIUM( | 107 source_textures[i].fID = gl->CreateAndConsumeTextureCHROMIUM( |
| 107 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 108 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 108 | 109 |
| 109 // TODO(dcastagna): avoid this copy once Skia supports native textures | 110 // TODO(dcastagna): avoid this copy once Skia supports native textures |
| 110 // with a texture target different than TEXTURE_2D. | 111 // with a texture target different than TEXTURE_2D. |
| 111 // crbug.com/505026 | 112 // crbug.com/505026 |
| 112 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { | 113 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { |
| 113 unsigned texture_copy = 0; | 114 unsigned texture_copy = 0; |
| 114 gl->GenTextures(1, &texture_copy); | 115 gl->GenTextures(1, &texture_copy); |
| 115 DCHECK(texture_copy); | 116 DCHECK(texture_copy); |
| 116 gl->BindTexture(GL_TEXTURE_2D, texture_copy); | 117 gl->BindTexture(GL_TEXTURE_2D, texture_copy); |
| 117 gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_textures[i], texture_copy, | 118 gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_textures[i].fID, |
| 118 GL_RGB, GL_UNSIGNED_BYTE, false, true, false); | 119 texture_copy, GL_RGB, GL_UNSIGNED_BYTE, false, |
| 120 true, false); | |
| 119 | 121 |
| 120 gl->DeleteTextures(1, &source_textures[i]); | 122 gl->DeleteTextures(1, &source_textures[i].fID); |
| 121 source_textures[i] = texture_copy; | 123 source_textures[i].fID = texture_copy; |
| 124 source_textures[i].fTarget = GL_TEXTURE_2D; | |
| 122 } | 125 } |
| 123 } | 126 } |
| 124 DCHECK_LE(source_textures[0], | 127 GrBackendObject handles[3] = { |
| 125 static_cast<unsigned>(std::numeric_limits<int>::max())); | 128 reinterpret_cast<GrBackendObject>(&source_textures[0]), |
| 126 DCHECK_LE(source_textures[1], | 129 reinterpret_cast<GrBackendObject>(&source_textures[1]), |
| 127 static_cast<unsigned>(std::numeric_limits<int>::max())); | 130 reinterpret_cast<GrBackendObject>(&source_textures[2])}; |
| 128 DCHECK_LE(source_textures[2], | |
| 129 static_cast<unsigned>(std::numeric_limits<int>::max())); | |
| 130 GrBackendObject handles[3] = {static_cast<int>(source_textures[0]), | |
| 131 static_cast<int>(source_textures[1]), | |
| 132 static_cast<int>(source_textures[2])}; | |
| 133 | 131 |
| 134 SkISize yuvSizes[] = { | 132 SkISize yuvSizes[] = { |
| 135 {ya_tex_size.width(), ya_tex_size.height()}, | 133 {ya_tex_size.width(), ya_tex_size.height()}, |
| 136 {uv_tex_size.width(), uv_tex_size.height()}, | 134 {uv_tex_size.width(), uv_tex_size.height()}, |
| 137 {uv_tex_size.width(), uv_tex_size.height()}, | 135 {uv_tex_size.width(), uv_tex_size.height()}, |
| 138 }; | 136 }; |
| 139 | 137 |
| 140 SkYUVColorSpace color_space = kRec601_SkYUVColorSpace; | 138 SkYUVColorSpace color_space = kRec601_SkYUVColorSpace; |
| 141 if (CheckColorSpace(video_frame, media::COLOR_SPACE_JPEG)) | 139 if (CheckColorSpace(video_frame, media::COLOR_SPACE_JPEG)) |
| 142 color_space = kJPEG_SkYUVColorSpace; | 140 color_space = kJPEG_SkYUVColorSpace; |
| 143 else if (CheckColorSpace(video_frame, media::COLOR_SPACE_HD_REC709)) | 141 else if (CheckColorSpace(video_frame, media::COLOR_SPACE_HD_REC709)) |
| 144 color_space = kRec709_SkYUVColorSpace; | 142 color_space = kRec709_SkYUVColorSpace; |
| 145 | 143 |
| 146 SkImage* img = SkImage::NewFromYUVTexturesCopy(context_3d.gr_context, | 144 SkImage* img = SkImage::NewFromYUVTexturesCopy(context_3d.gr_context, |
| 147 color_space, handles, yuvSizes, | 145 color_space, handles, yuvSizes, |
| 148 kTopLeft_GrSurfaceOrigin); | 146 kTopLeft_GrSurfaceOrigin); |
| 149 gl->DeleteTextures(3, source_textures); | 147 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format()); |
| 148 ++i) { | |
| 149 gl->DeleteTextures(1, &source_textures[i].fID); | |
| 150 } | |
| 150 return skia::AdoptRef(img); | 151 return skia::AdoptRef(img); |
| 151 } | 152 } |
| 152 | 153 |
| 153 // Creates a SkImage from a |video_frame| backed by native resources. | 154 // Creates a SkImage from a |video_frame| backed by native resources. |
| 154 // The SkImage will take ownership of the underlying resource. | 155 // The SkImage will take ownership of the underlying resource. |
| 155 skia::RefPtr<SkImage> NewSkImageFromVideoFrameNative( | 156 skia::RefPtr<SkImage> NewSkImageFromVideoFrameNative( |
| 156 VideoFrame* video_frame, | 157 VideoFrame* video_frame, |
| 157 const Context3D& context_3d) { | 158 const Context3D& context_3d) { |
| 158 DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() || | 159 DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() || |
| 159 PIXEL_FORMAT_XRGB == video_frame->format() || | 160 PIXEL_FORMAT_XRGB == video_frame->format() || |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 182 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 183 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 183 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 184 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
| 184 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 185 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 185 } | 186 } |
| 186 GrBackendTextureDesc desc; | 187 GrBackendTextureDesc desc; |
| 187 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | 188 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| 188 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 189 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| 189 desc.fWidth = video_frame->coded_size().width(); | 190 desc.fWidth = video_frame->coded_size().width(); |
| 190 desc.fHeight = video_frame->coded_size().height(); | 191 desc.fHeight = video_frame->coded_size().height(); |
| 191 desc.fConfig = kRGBA_8888_GrPixelConfig; | 192 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 192 DCHECK_LE(source_texture, | 193 GrGLTextureInfo sourceTextureInfo; |
|
Daniele Castagna
2015/12/16 19:30:18
nit: the name should be all lower case, with under
bsalomon
2015/12/16 20:06:36
Done.
| |
| 193 static_cast<unsigned>(std::numeric_limits<int>::max())); | 194 sourceTextureInfo.fID = source_texture; |
| 194 desc.fTextureHandle = static_cast<int>(source_texture); | 195 sourceTextureInfo.fTarget = GL_TEXTURE_2D; |
| 196 desc.fTextureHandle = reinterpret_cast<GrBackendObject>(&sourceTextureInfo); | |
| 195 return skia::AdoptRef( | 197 return skia::AdoptRef( |
| 196 SkImage::NewFromAdoptedTexture(context_3d.gr_context, desc)); | 198 SkImage::NewFromAdoptedTexture(context_3d.gr_context, desc)); |
| 197 } | 199 } |
| 198 | 200 |
| 199 } // anonymous namespace | 201 } // anonymous namespace |
| 200 | 202 |
| 201 // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. | 203 // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. |
| 202 class VideoImageGenerator : public SkImageGenerator { | 204 class VideoImageGenerator : public SkImageGenerator { |
| 203 public: | 205 public: |
| 204 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) | 206 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 } | 595 } |
| 594 | 596 |
| 595 void SkCanvasVideoRenderer::ResetCache() { | 597 void SkCanvasVideoRenderer::ResetCache() { |
| 596 DCHECK(thread_checker_.CalledOnValidThread()); | 598 DCHECK(thread_checker_.CalledOnValidThread()); |
| 597 // Clear cached values. | 599 // Clear cached values. |
| 598 last_image_ = nullptr; | 600 last_image_ = nullptr; |
| 599 last_timestamp_ = kNoTimestamp(); | 601 last_timestamp_ = kNoTimestamp(); |
| 600 } | 602 } |
| 601 | 603 |
| 602 } // namespace media | 604 } // namespace media |
| OLD | NEW |