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/blink/skcanvas_video_renderer.h" | 5 #include "media/blink/skcanvas_video_renderer.h" |
6 | 6 |
7 #include "gpu/GLES2/gl2extchromium.h" | 7 #include "gpu/GLES2/gl2extchromium.h" |
8 #include "gpu/command_buffer/client/gles2_interface.h" | 8 #include "gpu/command_buffer/client/gles2_interface.h" |
9 #include "gpu/command_buffer/common/mailbox_holder.h" | 9 #include "gpu/command_buffer/common/mailbox_holder.h" |
10 #include "media/base/video_frame.h" | 10 #include "media/base/video_frame.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 147 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
148 unsigned source_texture = 0; | 148 unsigned source_texture = 0; |
149 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { | 149 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { |
150 // TODO(dcastagna): At the moment Skia doesn't support targets different | 150 // TODO(dcastagna): At the moment Skia doesn't support targets different |
151 // than GL_TEXTURE_2D. Avoid this copy once | 151 // than GL_TEXTURE_2D. Avoid this copy once |
152 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. | 152 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. |
153 gl->GenTextures(1, &source_texture); | 153 gl->GenTextures(1, &source_texture); |
154 DCHECK(source_texture); | 154 DCHECK(source_texture); |
155 gl->BindTexture(GL_TEXTURE_2D, source_texture); | 155 gl->BindTexture(GL_TEXTURE_2D, source_texture); |
156 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 156 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
157 gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, | 157 gl, video_frame, GL_TEXTURE_2D, source_texture, GL_RGBA, |
158 false); | 158 GL_UNSIGNED_BYTE, 0, true, false); |
159 } else { | 159 } else { |
160 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); | 160 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); |
161 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 161 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
162 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 162 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
163 } | 163 } |
164 GrBackendTextureDesc desc; | 164 GrBackendTextureDesc desc; |
165 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | 165 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
166 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 166 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
167 desc.fWidth = video_frame->coded_size().width(); | 167 desc.fWidth = video_frame->coded_size().width(); |
168 desc.fHeight = video_frame->coded_size().height(); | 168 desc.fHeight = video_frame->coded_size().height(); |
169 desc.fConfig = kRGBA_8888_GrPixelConfig; | 169 desc.fConfig = kRGBA_8888_GrPixelConfig; |
170 desc.fTextureHandle = source_texture; | 170 desc.fTextureHandle = source_texture; |
171 return skia::AdoptRef( | 171 return skia::AdoptRef( |
172 SkImage::NewFromAdoptedTexture(context_3d.gr_context, desc)); | 172 SkImage::NewFromAdoptedTexture(context_3d.gr_context, desc)); |
173 } | 173 } |
174 | 174 |
| 175 void CopyVideoFrameSingleTextureToGLTextureInternal( |
| 176 gpu::gles2::GLES2Interface* gl, |
| 177 VideoFrame* video_frame, |
| 178 bool is_full_copy, |
| 179 unsigned int target, |
| 180 unsigned int texture, |
| 181 unsigned int internal_format, |
| 182 unsigned int type, |
| 183 int level, |
| 184 int xoffset, |
| 185 int yoffset, |
| 186 bool premultiply_alpha, |
| 187 bool flip_y) { |
| 188 DCHECK(video_frame); |
| 189 DCHECK(video_frame->HasTextures()); |
| 190 DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format())); |
| 191 |
| 192 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
| 193 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
| 194 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || |
| 195 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) |
| 196 << mailbox_holder.texture_target; |
| 197 |
| 198 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); |
| 199 uint32 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
| 200 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 201 |
| 202 // The video is stored in a unmultiplied format, so premultiply |
| 203 // if necessary. |
| 204 // Application itself needs to take care of setting the right |flip_y| |
| 205 // value down to get the expected result. |
| 206 // "flip_y == true" means to reverse the video orientation while |
| 207 // "flip_y == false" means to keep the intrinsic orientation. |
| 208 if (is_full_copy) { |
| 209 DCHECK(!xoffset && !yoffset); |
| 210 gl->CopyTextureCHROMIUM(target, source_texture, texture, internal_format, |
| 211 type, flip_y, premultiply_alpha, false); |
| 212 } else { |
| 213 DCHECK_EQ(static_cast<unsigned int>(GL_FALSE), internal_format); |
| 214 DCHECK_EQ(static_cast<unsigned int>(GL_FALSE), type); |
| 215 gl->CopySubTextureCHROMIUM( |
| 216 target, source_texture, texture, xoffset, yoffset, 0, 0, |
| 217 video_frame->natural_size().width(), |
| 218 video_frame->natural_size().height(), flip_y, premultiply_alpha, false); |
| 219 } |
| 220 |
| 221 gl->DeleteTextures(1, &source_texture); |
| 222 gl->Flush(); |
| 223 |
| 224 SyncPointClientImpl client(gl); |
| 225 video_frame->UpdateReleaseSyncPoint(&client); |
| 226 } |
| 227 |
175 } // anonymous namespace | 228 } // anonymous namespace |
176 | 229 |
177 // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. | 230 // Generates an RGB image from a VideoFrame. Convert YUV to RGB plain on GPU. |
178 class VideoImageGenerator : public SkImageGenerator { | 231 class VideoImageGenerator : public SkImageGenerator { |
179 public: | 232 public: |
180 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) | 233 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) |
181 : SkImageGenerator( | 234 : SkImageGenerator( |
182 SkImageInfo::MakeN32Premul(frame->visible_rect().width(), | 235 SkImageInfo::MakeN32Premul(frame->visible_rect().width(), |
183 frame->visible_rect().height())), | 236 frame->visible_rect().height())), |
184 frame_(frame) { | 237 frame_(frame) { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 case PIXEL_FORMAT_MJPEG: | 579 case PIXEL_FORMAT_MJPEG: |
527 case PIXEL_FORMAT_UNKNOWN: | 580 case PIXEL_FORMAT_UNKNOWN: |
528 NOTREACHED(); | 581 NOTREACHED(); |
529 } | 582 } |
530 } | 583 } |
531 | 584 |
532 // static | 585 // static |
533 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 586 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
534 gpu::gles2::GLES2Interface* gl, | 587 gpu::gles2::GLES2Interface* gl, |
535 VideoFrame* video_frame, | 588 VideoFrame* video_frame, |
| 589 unsigned int target, |
536 unsigned int texture, | 590 unsigned int texture, |
537 unsigned int internal_format, | 591 unsigned int internal_format, |
538 unsigned int type, | 592 unsigned int type, |
| 593 int level, |
539 bool premultiply_alpha, | 594 bool premultiply_alpha, |
540 bool flip_y) { | 595 bool flip_y) { |
541 DCHECK(video_frame); | 596 CopyVideoFrameSingleTextureToGLTextureInternal( |
542 DCHECK(video_frame->HasTextures()); | 597 gl, video_frame, true, target, texture, internal_format, type, level, 0, |
543 DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format())); | 598 0, premultiply_alpha, flip_y); |
| 599 } |
544 | 600 |
545 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); | 601 // static |
546 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 602 void SkCanvasVideoRenderer::CopySubVideoFrameSingleTextureToGLTexture( |
547 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || | 603 gpu::gles2::GLES2Interface* gl, |
548 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) | 604 VideoFrame* video_frame, |
549 << mailbox_holder.texture_target; | 605 unsigned int target, |
550 | 606 unsigned int texture, |
551 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); | 607 int level, |
552 uint32 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 608 int xoffset, |
553 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 609 int yoffset, |
554 | 610 bool premultiply_alpha, |
555 // The video is stored in a unmultiplied format, so premultiply | 611 bool flip_y) { |
556 // if necessary. | 612 CopyVideoFrameSingleTextureToGLTextureInternal( |
557 // Application itself needs to take care of setting the right |flip_y| | 613 gl, video_frame, false, target, texture, GL_FALSE, GL_FALSE, level, |
558 // value down to get the expected result. | 614 xoffset, yoffset, premultiply_alpha, flip_y); |
559 // "flip_y == true" means to reverse the video orientation while | |
560 // "flip_y == false" means to keep the intrinsic orientation. | |
561 gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_texture, texture, | |
562 internal_format, type, | |
563 flip_y, premultiply_alpha, false); | |
564 | |
565 gl->DeleteTextures(1, &source_texture); | |
566 gl->Flush(); | |
567 | |
568 SyncPointClientImpl client(gl); | |
569 video_frame->UpdateReleaseSyncPoint(&client); | |
570 } | 615 } |
571 | 616 |
572 void SkCanvasVideoRenderer::ResetCache() { | 617 void SkCanvasVideoRenderer::ResetCache() { |
573 // Clear cached values. | 618 // Clear cached values. |
574 last_image_ = nullptr; | 619 last_image_ = nullptr; |
575 last_timestamp_ = kNoTimestamp(); | 620 last_timestamp_ = kNoTimestamp(); |
576 } | 621 } |
577 | 622 |
578 } // namespace media | 623 } // namespace media |
OLD | NEW |