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 |