Chromium Code Reviews| 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/stream_texture_factory_android_synchron ous_impl.h" | 5 #include "content/renderer/media/android/stream_texture_factory_android_synchron ous_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/callback.h" | |
| 11 #include "base/location.h" | |
| 12 #include "base/memory/weak_ptr.h" | |
| 13 #include "base/message_loop/message_loop_proxy.h" | |
| 14 #include "base/process/process.h" | |
| 15 #include "base/synchronization/lock.h" | |
| 16 #include "cc/output/context_provider.h" | |
| 17 #include "content/common/android/surface_texture_peer.h" | |
| 18 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" | |
| 19 #include "ui/gl/android/surface_texture_bridge.h" | |
| 20 | |
| 7 namespace content { | 21 namespace content { |
| 8 | 22 |
| 9 StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl() {} | 23 namespace { |
| 24 | |
| 25 class StreamTextureProxyImpl | |
| 26 : public StreamTextureProxy, | |
| 27 public base::SupportsWeakPtr<StreamTextureProxyImpl> { | |
| 28 public: | |
| 29 explicit StreamTextureProxyImpl( | |
| 30 StreamTextureFactorySynchronousImpl::ContextProvider* provider); | |
| 31 virtual ~StreamTextureProxyImpl(); | |
| 32 | |
| 33 // StreamTextureProxy implementation: | |
| 34 virtual void BindToCurrentThread(int32 stream_id) OVERRIDE; | |
| 35 virtual bool IsBoundToThread() OVERRIDE { return loop_.get() != NULL; } | |
| 36 virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE; | |
| 37 virtual void Release() OVERRIDE; | |
| 38 | |
| 39 private: | |
| 40 void OnFrameAvailable(); | |
| 41 | |
| 42 scoped_refptr<base::MessageLoopProxy> loop_; | |
| 43 base::Lock client_lock_; | |
| 44 cc::VideoFrameProvider::Client* client_; | |
| 45 base::Closure callback_; | |
| 46 | |
| 47 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> | |
| 48 context_provider_; | |
| 49 scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_; | |
| 50 | |
| 51 float current_matrix_[16]; | |
| 52 bool has_updated_; | |
| 53 | |
| 54 DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl); | |
| 55 }; | |
| 56 | |
| 57 StreamTextureProxyImpl::StreamTextureProxyImpl( | |
| 58 StreamTextureFactorySynchronousImpl::ContextProvider* provider) | |
| 59 : context_provider_(provider), has_updated_(false) { | |
| 60 std::fill(current_matrix_, current_matrix_ + 16, 0); | |
| 61 } | |
| 62 | |
| 63 StreamTextureProxyImpl::~StreamTextureProxyImpl() {} | |
| 64 | |
| 65 void StreamTextureProxyImpl::Release() { | |
| 66 SetClient(NULL); | |
| 67 if (loop_.get() && loop_.get() != base::MessageLoopProxy::current()) | |
| 68 loop_->DeleteSoon(FROM_HERE, this); | |
| 69 else | |
| 70 delete this; | |
| 71 } | |
| 72 | |
| 73 void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) { | |
| 74 base::AutoLock lock(client_lock_); | |
| 75 client_ = client; | |
| 76 } | |
| 77 | |
| 78 void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) { | |
| 79 if (loop_) { | |
| 80 LOG(ERROR) << "Already bound to thread."; | |
|
boliu
2013/08/20 21:33:49
I think this can be called multiple times if the v
no sievers
2013/08/20 21:59:58
Argh, that was never intended, but ok.
| |
| 81 return; | |
| 82 } | |
| 83 loop_ = base::MessageLoopProxy::current(); | |
|
boliu
2013/08/20 21:33:49
Hmm...should we have two thread checkers, one for
no sievers
2013/08/20 21:59:58
Constructor, Release and SetClient can be called o
| |
| 84 DCHECK(callback_.is_null()); | |
| 85 | |
| 86 surface_texture_ = context_provider_->GetSurfaceTexture(stream_id); | |
| 87 if (!surface_texture_) { | |
| 88 LOG(ERROR) << "Failed to get SurfaceTexture for stream."; | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 callback_ = | |
| 93 base::Bind(&StreamTextureProxyImpl::OnFrameAvailable, AsWeakPtr()); | |
| 94 surface_texture_->SetFrameAvailableCallback(callback_); | |
| 95 } | |
| 96 | |
| 97 void StreamTextureProxyImpl::OnFrameAvailable() { | |
| 98 // GetTransformMatrix only returns something valid after both is true: | |
| 99 // - OnFrameAvailable was called | |
| 100 // - we called UpdateTexImage | |
| 101 if (has_updated_) { | |
| 102 float matrix[16]; | |
| 103 surface_texture_->GetTransformMatrix(matrix); | |
| 104 | |
| 105 if (memcmp(current_matrix_, matrix, sizeof(matrix)) != 0) { | |
| 106 memcpy(current_matrix_, matrix, sizeof(matrix)); | |
| 107 | |
| 108 base::AutoLock lock(client_lock_); | |
| 109 if (client_) | |
| 110 client_->DidUpdateMatrix(current_matrix_); | |
| 111 } | |
| 112 } | |
| 113 // OnFrameAvailable being called a second time implies that we called | |
| 114 // updateTexImage since after we received the first frame. | |
| 115 has_updated_ = true; | |
| 116 | |
| 117 base::AutoLock lock(client_lock_); | |
| 118 if (client_) | |
| 119 client_->DidReceiveFrame(); | |
| 120 } | |
| 121 | |
| 122 } // namespace | |
| 123 | |
| 124 StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl( | |
| 125 ContextProvider* context_provider, | |
| 126 int view_id) | |
| 127 : context_provider_(context_provider), view_id_(view_id) {} | |
| 128 | |
| 10 StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {} | 129 StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {} |
| 11 | 130 |
| 12 StreamTextureProxy* StreamTextureFactorySynchronousImpl::CreateProxy() { | 131 StreamTextureProxy* StreamTextureFactorySynchronousImpl::CreateProxy() { |
| 13 return NULL; | 132 return new StreamTextureProxyImpl(context_provider_); |
| 14 } | 133 } |
| 15 | 134 |
| 16 void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id, | 135 void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id, |
| 17 int player_id) {} | 136 int player_id) { |
| 137 scoped_refptr<gfx::SurfaceTextureBridge> surface_texture = | |
| 138 context_provider_->GetSurfaceTexture(stream_id); | |
| 139 if (surface_texture) { | |
| 140 SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer( | |
| 141 base::Process::Current().handle(), | |
| 142 surface_texture, | |
| 143 view_id_, | |
| 144 player_id); | |
| 145 } | |
| 146 } | |
| 18 | 147 |
| 19 unsigned StreamTextureFactorySynchronousImpl::CreateStreamTexture( | 148 unsigned StreamTextureFactorySynchronousImpl::CreateStreamTexture( |
| 20 unsigned texture_target, | 149 unsigned texture_target, |
| 21 unsigned* texture_id, | 150 unsigned* texture_id, |
| 22 gpu::Mailbox* texture_mailbox, | 151 gpu::Mailbox* texture_mailbox, |
| 23 unsigned* texture_mailbox_sync_point) { | 152 unsigned* texture_mailbox_sync_point) { |
| 24 return 0; | 153 WebKit::WebGraphicsContext3D* context = context_provider_->Context3d(); |
| 154 unsigned stream_id = 0; | |
| 155 if (context->makeContextCurrent()) { | |
| 156 *texture_id = context->createTexture(); | |
| 157 stream_id = context->createStreamTextureCHROMIUM(*texture_id); | |
| 158 | |
| 159 context->genMailboxCHROMIUM(texture_mailbox->name); | |
| 160 context->bindTexture(texture_target, *texture_id); | |
| 161 context->produceTextureCHROMIUM(texture_target, texture_mailbox->name); | |
| 162 | |
| 163 context->flush(); | |
| 164 *texture_mailbox_sync_point = context->insertSyncPoint(); | |
| 165 } | |
| 166 return stream_id; | |
| 25 } | 167 } |
| 26 | 168 |
| 27 void StreamTextureFactorySynchronousImpl::DestroyStreamTexture( | 169 void StreamTextureFactorySynchronousImpl::DestroyStreamTexture( |
| 28 unsigned texture_id) {} | 170 unsigned texture_id) { |
| 171 WebKit::WebGraphicsContext3D* context = context_provider_->Context3d(); | |
| 172 if (context->makeContextCurrent()) { | |
| 173 context->destroyStreamTextureCHROMIUM(texture_id); | |
| 174 context->deleteTexture(texture_id); | |
| 175 context->flush(); | |
| 176 } | |
| 177 } | |
| 29 | 178 |
| 30 void StreamTextureFactorySynchronousImpl::SetStreamTextureSize( | 179 void StreamTextureFactorySynchronousImpl::SetStreamTextureSize( |
| 31 int32 texture_id, | 180 int32 stream_id, |
| 32 const gfx::Size& size) {} | 181 const gfx::Size& size) {} |
| 33 | 182 |
| 34 } // namespace content | 183 } // namespace content |
| OLD | NEW |