| 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 "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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 // We delete the temporary resource if it is not used for 3 seconds. | 52 // We delete the temporary resource if it is not used for 3 seconds. |
| 53 const int kTemporaryResourceDeletionDelay = 3; // Seconds; | 53 const int kTemporaryResourceDeletionDelay = 3; // Seconds; |
| 54 | 54 |
| 55 bool CheckColorSpace(const VideoFrame* video_frame, ColorSpace color_space) { | 55 bool CheckColorSpace(const VideoFrame* video_frame, ColorSpace color_space) { |
| 56 int result; | 56 int result; |
| 57 return video_frame->metadata()->GetInteger(VideoFrameMetadata::COLOR_SPACE, | 57 return video_frame->metadata()->GetInteger(VideoFrameMetadata::COLOR_SPACE, |
| 58 &result) && | 58 &result) && |
| 59 result == color_space; | 59 result == color_space; |
| 60 } | 60 } |
| 61 | 61 |
| 62 class SyncPointClientImpl : public VideoFrame::SyncPointClient { | 62 class SyncTokenClientImpl : public VideoFrame::SyncTokenClient { |
| 63 public: | 63 public: |
| 64 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} | 64 explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} |
| 65 ~SyncPointClientImpl() override {} | 65 ~SyncTokenClientImpl() override {} |
| 66 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); } | 66 uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); } |
| 67 void WaitSyncPoint(uint32 sync_point) override { | 67 void WaitSyncToken(const gpu::SyncToken& sync_token) override { |
| 68 gl_->WaitSyncPointCHROMIUM(sync_point); | 68 gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); |
| 69 } | 69 } |
| 70 | 70 |
| 71 private: | 71 private: |
| 72 gpu::gles2::GLES2Interface* gl_; | 72 gpu::gles2::GLES2Interface* gl_; |
| 73 | 73 |
| 74 DISALLOW_IMPLICIT_CONSTRUCTORS(SyncPointClientImpl); | 74 DISALLOW_IMPLICIT_CONSTRUCTORS(SyncTokenClientImpl); |
| 75 }; | 75 }; |
| 76 | 76 |
| 77 skia::RefPtr<SkImage> NewSkImageFromVideoFrameYUVTextures( | 77 skia::RefPtr<SkImage> NewSkImageFromVideoFrameYUVTextures( |
| 78 const VideoFrame* video_frame, | 78 const VideoFrame* video_frame, |
| 79 const Context3D& context_3d) { | 79 const Context3D& context_3d) { |
| 80 // Support only TEXTURE_YUV_420. | 80 // Support only TEXTURE_YUV_420. |
| 81 DCHECK(video_frame->HasTextures()); | 81 DCHECK(video_frame->HasTextures()); |
| 82 DCHECK_EQ(media::PIXEL_FORMAT_I420, video_frame->format()); | 82 DCHECK_EQ(media::PIXEL_FORMAT_I420, video_frame->format()); |
| 83 DCHECK_EQ(3u, media::VideoFrame::NumPlanes(video_frame->format())); | 83 DCHECK_EQ(3u, media::VideoFrame::NumPlanes(video_frame->format())); |
| 84 | 84 |
| 85 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 85 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 86 DCHECK(gl); | 86 DCHECK(gl); |
| 87 gfx::Size ya_tex_size = video_frame->coded_size(); | 87 gfx::Size ya_tex_size = video_frame->coded_size(); |
| 88 gfx::Size uv_tex_size((ya_tex_size.width() + 1) / 2, | 88 gfx::Size uv_tex_size((ya_tex_size.width() + 1) / 2, |
| 89 (ya_tex_size.height() + 1) / 2); | 89 (ya_tex_size.height() + 1) / 2); |
| 90 | 90 |
| 91 unsigned source_textures[3] = {0}; | 91 unsigned source_textures[3] = {0}; |
| 92 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format()); | 92 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format()); |
| 93 ++i) { | 93 ++i) { |
| 94 // Get the texture from the mailbox and wrap it in a GrTexture. | 94 // Get the texture from the mailbox and wrap it in a GrTexture. |
| 95 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); | 95 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); |
| 96 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 96 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
| 97 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES || | 97 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES || |
| 98 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB); | 98 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB); |
| 99 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); | 99 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 100 source_textures[i] = gl->CreateAndConsumeTextureCHROMIUM( | 100 source_textures[i] = gl->CreateAndConsumeTextureCHROMIUM( |
| 101 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 101 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 102 | 102 |
| 103 // TODO(dcastagna): avoid this copy once Skia supports native textures | 103 // TODO(dcastagna): avoid this copy once Skia supports native textures |
| 104 // with a texture target different than TEXTURE_2D. | 104 // with a texture target different than TEXTURE_2D. |
| 105 // crbug.com/505026 | 105 // crbug.com/505026 |
| 106 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { | 106 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { |
| 107 unsigned texture_copy = 0; | 107 unsigned texture_copy = 0; |
| 108 gl->GenTextures(1, &texture_copy); | 108 gl->GenTextures(1, &texture_copy); |
| 109 DCHECK(texture_copy); | 109 DCHECK(texture_copy); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 // TODO(dcastagna): At the moment Skia doesn't support targets different | 158 // TODO(dcastagna): At the moment Skia doesn't support targets different |
| 159 // than GL_TEXTURE_2D. Avoid this copy once | 159 // than GL_TEXTURE_2D. Avoid this copy once |
| 160 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. | 160 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. |
| 161 gl->GenTextures(1, &source_texture); | 161 gl->GenTextures(1, &source_texture); |
| 162 DCHECK(source_texture); | 162 DCHECK(source_texture); |
| 163 gl->BindTexture(GL_TEXTURE_2D, source_texture); | 163 gl->BindTexture(GL_TEXTURE_2D, source_texture); |
| 164 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 164 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
| 165 gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, | 165 gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, |
| 166 false); | 166 false); |
| 167 } else { | 167 } else { |
| 168 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); | 168 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 169 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 169 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
| 170 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 170 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 171 } | 171 } |
| 172 GrBackendTextureDesc desc; | 172 GrBackendTextureDesc desc; |
| 173 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | 173 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| 174 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 174 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| 175 desc.fWidth = video_frame->coded_size().width(); | 175 desc.fWidth = video_frame->coded_size().width(); |
| 176 desc.fHeight = video_frame->coded_size().height(); | 176 desc.fHeight = video_frame->coded_size().height(); |
| 177 desc.fConfig = kRGBA_8888_GrPixelConfig; | 177 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 178 desc.fTextureHandle = source_texture; | 178 desc.fTextureHandle = source_texture; |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 canvas->drawImage(last_image_.get(), 0, 0, &paint); | 411 canvas->drawImage(last_image_.get(), 0, 0, &paint); |
| 412 } | 412 } |
| 413 | 413 |
| 414 if (need_transform) | 414 if (need_transform) |
| 415 canvas->restore(); | 415 canvas->restore(); |
| 416 // Make sure to flush so we can remove the videoframe from the generator. | 416 // Make sure to flush so we can remove the videoframe from the generator. |
| 417 canvas->flush(); | 417 canvas->flush(); |
| 418 | 418 |
| 419 if (video_frame->HasTextures()) { | 419 if (video_frame->HasTextures()) { |
| 420 DCHECK(gl); | 420 DCHECK(gl); |
| 421 SyncPointClientImpl client(gl); | 421 SyncTokenClientImpl client(gl); |
| 422 video_frame->UpdateReleaseSyncPoint(&client); | 422 video_frame->UpdateReleaseSyncToken(&client); |
| 423 } | 423 } |
| 424 } | 424 } |
| 425 | 425 |
| 426 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, | 426 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 427 SkCanvas* canvas, | 427 SkCanvas* canvas, |
| 428 const Context3D& context_3d) { | 428 const Context3D& context_3d) { |
| 429 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), 0xff, | 429 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), 0xff, |
| 430 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d); | 430 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d); |
| 431 } | 431 } |
| 432 | 432 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 DCHECK(video_frame); | 547 DCHECK(video_frame); |
| 548 DCHECK(video_frame->HasTextures()); | 548 DCHECK(video_frame->HasTextures()); |
| 549 DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format())); | 549 DCHECK_EQ(1u, VideoFrame::NumPlanes(video_frame->format())); |
| 550 | 550 |
| 551 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); | 551 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
| 552 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 552 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
| 553 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || | 553 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || |
| 554 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) | 554 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) |
| 555 << mailbox_holder.texture_target; | 555 << mailbox_holder.texture_target; |
| 556 | 556 |
| 557 gl->WaitSyncPointCHROMIUM(mailbox_holder.sync_point); | 557 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 558 uint32 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 558 uint32 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
| 559 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 559 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 560 | 560 |
| 561 // The video is stored in a unmultiplied format, so premultiply | 561 // The video is stored in a unmultiplied format, so premultiply |
| 562 // if necessary. | 562 // if necessary. |
| 563 // Application itself needs to take care of setting the right |flip_y| | 563 // Application itself needs to take care of setting the right |flip_y| |
| 564 // value down to get the expected result. | 564 // value down to get the expected result. |
| 565 // "flip_y == true" means to reverse the video orientation while | 565 // "flip_y == true" means to reverse the video orientation while |
| 566 // "flip_y == false" means to keep the intrinsic orientation. | 566 // "flip_y == false" means to keep the intrinsic orientation. |
| 567 gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_texture, texture, | 567 gl->CopyTextureCHROMIUM(GL_TEXTURE_2D, source_texture, texture, |
| 568 internal_format, type, flip_y, premultiply_alpha, | 568 internal_format, type, flip_y, premultiply_alpha, |
| 569 false); | 569 false); |
| 570 | 570 |
| 571 gl->DeleteTextures(1, &source_texture); | 571 gl->DeleteTextures(1, &source_texture); |
| 572 gl->Flush(); | 572 gl->Flush(); |
| 573 | 573 |
| 574 SyncPointClientImpl client(gl); | 574 SyncTokenClientImpl client(gl); |
| 575 video_frame->UpdateReleaseSyncPoint(&client); | 575 video_frame->UpdateReleaseSyncToken(&client); |
| 576 } | 576 } |
| 577 | 577 |
| 578 void SkCanvasVideoRenderer::ResetCache() { | 578 void SkCanvasVideoRenderer::ResetCache() { |
| 579 // Clear cached values. | 579 // Clear cached values. |
| 580 last_image_ = nullptr; | 580 last_image_ = nullptr; |
| 581 last_timestamp_ = kNoTimestamp(); | 581 last_timestamp_ = kNoTimestamp(); |
| 582 } | 582 } |
| 583 | 583 |
| 584 } // namespace media | 584 } // namespace media |
| OLD | NEW |