| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/renderer/media/android/webmediaplayer_android.h" | 5 #include "content/renderer/media/android/webmediaplayer_android.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" | 58 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" |
| 59 #include "third_party/WebKit/public/platform/WebMediaPlayerEncryptedMediaClient.
h" | 59 #include "third_party/WebKit/public/platform/WebMediaPlayerEncryptedMediaClient.
h" |
| 60 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" | 60 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" |
| 61 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | 61 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
| 62 #include "third_party/WebKit/public/platform/WebString.h" | 62 #include "third_party/WebKit/public/platform/WebString.h" |
| 63 #include "third_party/WebKit/public/platform/WebURL.h" | 63 #include "third_party/WebKit/public/platform/WebURL.h" |
| 64 #include "third_party/WebKit/public/web/WebDocument.h" | 64 #include "third_party/WebKit/public/web/WebDocument.h" |
| 65 #include "third_party/WebKit/public/web/WebFrame.h" | 65 #include "third_party/WebKit/public/web/WebFrame.h" |
| 66 #include "third_party/WebKit/public/web/WebView.h" | 66 #include "third_party/WebKit/public/web/WebView.h" |
| 67 #include "third_party/skia/include/core/SkCanvas.h" | 67 #include "third_party/skia/include/core/SkCanvas.h" |
| 68 #include "third_party/skia/include/core/SkImage.h" |
| 68 #include "third_party/skia/include/core/SkPaint.h" | 69 #include "third_party/skia/include/core/SkPaint.h" |
| 69 #include "third_party/skia/include/core/SkTypeface.h" | 70 #include "third_party/skia/include/core/SkTypeface.h" |
| 70 #include "third_party/skia/include/gpu/GrContext.h" | |
| 71 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | |
| 72 #include "ui/gfx/image/image.h" | 71 #include "ui/gfx/image/image.h" |
| 73 | 72 |
| 74 static const uint32_t kGLTextureExternalOES = 0x8D65; | 73 static const uint32_t kGLTextureExternalOES = 0x8D65; |
| 75 static const int kSDKVersionToSupportSecurityOriginCheck = 20; | 74 static const int kSDKVersionToSupportSecurityOriginCheck = 20; |
| 76 | 75 |
| 77 using blink::WebMediaPlayer; | 76 using blink::WebMediaPlayer; |
| 78 using blink::WebSize; | 77 using blink::WebSize; |
| 79 using blink::WebString; | 78 using blink::WebString; |
| 80 using blink::WebURL; | 79 using blink::WebURL; |
| 81 using gpu::gles2::GLES2Interface; | 80 using gpu::gles2::GLES2Interface; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 102 const scoped_refptr<content::StreamTextureFactory>& factories, | 101 const scoped_refptr<content::StreamTextureFactory>& factories, |
| 103 uint32_t texture_id, | 102 uint32_t texture_id, |
| 104 const gpu::SyncToken& sync_token) { | 103 const gpu::SyncToken& sync_token) { |
| 105 GLES2Interface* gl = factories->ContextGL(); | 104 GLES2Interface* gl = factories->ContextGL(); |
| 106 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); | 105 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); |
| 107 gl->DeleteTextures(1, &texture_id); | 106 gl->DeleteTextures(1, &texture_id); |
| 108 // Flush to ensure that the stream texture gets deleted in a timely fashion. | 107 // Flush to ensure that the stream texture gets deleted in a timely fashion. |
| 109 gl->ShallowFlushCHROMIUM(); | 108 gl->ShallowFlushCHROMIUM(); |
| 110 } | 109 } |
| 111 | 110 |
| 112 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap, | |
| 113 const gfx::Size& size) { | |
| 114 return bitmap->getTexture() && bitmap->width() == size.width() && | |
| 115 bitmap->height() == size.height(); | |
| 116 } | |
| 117 | |
| 118 bool AllocateSkBitmapTexture(GrContext* gr, | |
| 119 SkBitmap* bitmap, | |
| 120 const gfx::Size& size) { | |
| 121 DCHECK(gr); | |
| 122 GrTextureDesc desc; | |
| 123 // Use kRGBA_8888_GrPixelConfig, not kSkia8888_GrPixelConfig, to avoid | |
| 124 // RGBA to BGRA conversion. | |
| 125 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
| 126 // kRenderTarget_GrTextureFlagBit avoids a copy before readback in skia. | |
| 127 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
| 128 desc.fSampleCnt = 0; | |
| 129 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | |
| 130 desc.fWidth = size.width(); | |
| 131 desc.fHeight = size.height(); | |
| 132 sk_sp<GrTexture> texture(gr->textureProvider()->refScratchTexture( | |
| 133 desc, GrTextureProvider::kExact_ScratchTexMatch)); | |
| 134 if (!texture.get()) | |
| 135 return false; | |
| 136 | |
| 137 SkImageInfo info = SkImageInfo::MakeN32Premul(desc.fWidth, desc.fHeight); | |
| 138 SkGrPixelRef* pixel_ref = new SkGrPixelRef(info, texture.get()); | |
| 139 if (!pixel_ref) | |
| 140 return false; | |
| 141 bitmap->setInfo(info); | |
| 142 bitmap->setPixelRef(pixel_ref)->unref(); | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient { | 111 class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient { |
| 147 public: | 112 public: |
| 148 explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} | 113 explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} |
| 149 ~SyncTokenClientImpl() override {} | 114 ~SyncTokenClientImpl() override {} |
| 150 void GenerateSyncToken(gpu::SyncToken* sync_token) override { | 115 void GenerateSyncToken(gpu::SyncToken* sync_token) override { |
| 151 const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM(); | 116 const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM(); |
| 152 gl_->ShallowFlushCHROMIUM(); | 117 gl_->ShallowFlushCHROMIUM(); |
| 153 gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData()); | 118 gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData()); |
| 154 } | 119 } |
| 155 void WaitSyncToken(const gpu::SyncToken& sync_token) override { | 120 void WaitSyncToken(const gpu::SyncToken& sync_token) override { |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 unsigned char alpha, | 617 unsigned char alpha, |
| 653 SkXfermode::Mode mode) { | 618 SkXfermode::Mode mode) { |
| 654 DCHECK(main_thread_checker_.CalledOnValidThread()); | 619 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 655 std::unique_ptr<blink::WebGraphicsContext3DProvider> provider( | 620 std::unique_ptr<blink::WebGraphicsContext3DProvider> provider( |
| 656 blink::Platform::current() | 621 blink::Platform::current() |
| 657 ->createSharedOffscreenGraphicsContext3DProvider()); | 622 ->createSharedOffscreenGraphicsContext3DProvider()); |
| 658 if (!provider) | 623 if (!provider) |
| 659 return; | 624 return; |
| 660 gpu::gles2::GLES2Interface* gl = provider->contextGL(); | 625 gpu::gles2::GLES2Interface* gl = provider->contextGL(); |
| 661 | 626 |
| 662 // Copy video texture into a RGBA texture based bitmap first as video texture | 627 scoped_refptr<VideoFrame> video_frame; |
| 663 // on Android is GL_TEXTURE_EXTERNAL_OES which is not supported by Skia yet. | 628 { |
| 664 // The bitmap's size needs to be the same as the video and use naturalSize() | 629 base::AutoLock auto_lock(current_frame_lock_); |
| 665 // here. Check if we could reuse existing texture based bitmap. | 630 video_frame = current_frame_; |
| 666 // Otherwise, release existing texture based bitmap and allocate | |
| 667 // a new one based on video size. | |
| 668 if (!IsSkBitmapProperlySizedTexture(&bitmap_, naturalSize())) { | |
| 669 if (!AllocateSkBitmapTexture(provider->grContext(), &bitmap_, | |
| 670 naturalSize())) { | |
| 671 return; | |
| 672 } | |
| 673 } | 631 } |
| 674 | 632 |
| 675 unsigned textureId = skia::GrBackendObjectToGrGLTextureInfo( | 633 if (!video_frame.get() || !video_frame->HasTextures()) |
| 676 (bitmap_.getTexture())->getTextureHandle()) | |
| 677 ->fID; | |
| 678 if (!copyVideoTextureToPlatformTexture(gl, textureId, GL_RGBA, | |
| 679 GL_UNSIGNED_BYTE, true, false)) { | |
| 680 return; | 634 return; |
| 681 } | 635 DCHECK_EQ(1u, media::VideoFrame::NumPlanes(video_frame->format())); |
| 636 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
| 682 | 637 |
| 683 // Ensure SkBitmap to make the latest change by external source visible. | 638 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 684 bitmap_.notifyPixelsChanged(); | |
| 685 | 639 |
| 686 // Draw the texture based bitmap onto the Canvas. If the canvas is | 640 uint32_t src_texture = gl->CreateAndConsumeTextureCHROMIUM( |
| 641 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 642 |
| 643 GrGLTextureInfo texture_info; |
| 644 texture_info.fID = src_texture; |
| 645 texture_info.fTarget = mailbox_holder.texture_target; |
| 646 |
| 647 GrBackendTextureDesc desc; |
| 648 desc.fWidth = naturalSize().width; |
| 649 desc.fHeight = naturalSize().height; |
| 650 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| 651 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 652 desc.fSampleCnt = 0; |
| 653 desc.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(texture_info); |
| 654 |
| 655 sk_sp<SkImage> image(SkImage::MakeFromTexture(provider->grContext(), desc, |
| 656 kOpaque_SkAlphaType)); |
| 657 if (!image) |
| 658 return; |
| 659 |
| 660 // Draw the texture based image onto the Canvas. If the canvas is |
| 687 // hardware based, this will do a GPU-GPU texture copy. | 661 // hardware based, this will do a GPU-GPU texture copy. |
| 688 // If the canvas is software based, the texture based bitmap will be | 662 // If the canvas is software based, the texture based bitmap will be |
| 689 // readbacked to system memory then draw onto the canvas. | 663 // readbacked to system memory then draw onto the canvas. |
| 690 SkRect dest; | 664 SkRect dest; |
| 691 dest.set(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); | 665 dest.set(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); |
| 692 SkPaint paint; | 666 SkPaint paint; |
| 693 paint.setAlpha(alpha); | 667 paint.setAlpha(alpha); |
| 694 paint.setXfermodeMode(mode); | 668 paint.setXfermodeMode(mode); |
| 695 // It is not necessary to pass the dest into the drawBitmap call since all | 669 // It is not necessary to pass the dest into the drawBitmap call since all |
| 696 // the context have been set up before calling paintCurrentFrameInContext. | 670 // the context have been set up before calling paintCurrentFrameInContext. |
| 697 canvas->drawBitmapRect(bitmap_, dest, &paint); | 671 canvas->drawImageRect(image, dest, &paint); |
| 672 |
| 673 // Ensure the Skia draw of the GL texture is flushed to GL, delete the |
| 674 // mailboxed texture from this context, and then signal that we're done with |
| 675 // the video frame. |
| 698 canvas->flush(); | 676 canvas->flush(); |
| 677 gl->DeleteTextures(1, &src_texture); |
| 678 gl->Flush(); |
| 679 SyncTokenClientImpl client(gl); |
| 680 video_frame->UpdateReleaseSyncToken(&client); |
| 699 } | 681 } |
| 700 | 682 |
| 701 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( | 683 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( |
| 702 gpu::gles2::GLES2Interface* gl, | 684 gpu::gles2::GLES2Interface* gl, |
| 703 unsigned int texture, | 685 unsigned int texture, |
| 704 unsigned int internal_format, | 686 unsigned int internal_format, |
| 705 unsigned int type, | 687 unsigned int type, |
| 706 bool premultiply_alpha, | 688 bool premultiply_alpha, |
| 707 bool flip_y) { | 689 bool flip_y) { |
| 708 DCHECK(main_thread_checker_.CalledOnValidThread()); | 690 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1680 result = PREDICTION_RESULT_PATH_BASED_WAS_BETTER; | 1662 result = PREDICTION_RESULT_PATH_BASED_WAS_BETTER; |
| 1681 } else if (is_hls_url == is_hls) { | 1663 } else if (is_hls_url == is_hls) { |
| 1682 result = PREDICTION_RESULT_URL_BASED_WAS_BETTER; | 1664 result = PREDICTION_RESULT_URL_BASED_WAS_BETTER; |
| 1683 } | 1665 } |
| 1684 UMA_HISTOGRAM_ENUMERATION( | 1666 UMA_HISTOGRAM_ENUMERATION( |
| 1685 "Media.Android.IsHttpLiveStreamingMediaPredictionResult", | 1667 "Media.Android.IsHttpLiveStreamingMediaPredictionResult", |
| 1686 result, PREDICTION_RESULT_MAX); | 1668 result, PREDICTION_RESULT_MAX); |
| 1687 } | 1669 } |
| 1688 | 1670 |
| 1689 } // namespace content | 1671 } // namespace content |
| OLD | NEW |