| Index: content/renderer/media/android/stream_texture_factory_synchronous_impl.cc
|
| diff --git a/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc b/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc
|
| index 20c8ee7ae1ab6f16ec19b736b342b4d222f35803..37aba504e381fd8c9f37028e57a715f2de1cfa87 100644
|
| --- a/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc
|
| +++ b/content/renderer/media/android/stream_texture_factory_synchronous_impl.cc
|
| @@ -34,22 +34,24 @@ class StreamTextureProxyImpl
|
| virtual ~StreamTextureProxyImpl();
|
|
|
| // StreamTextureProxy implementation:
|
| - virtual void BindToCurrentThread(int32 stream_id) OVERRIDE;
|
| - virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE;
|
| + virtual void Bind(int32 stream_id,
|
| + cc::VideoFrameProvider::Client* client,
|
| + scoped_refptr<base::MessageLoopProxy> loop) OVERRIDE;
|
| virtual void Release() OVERRIDE;
|
|
|
| private:
|
| + void BindOnThread(int32 stream_id, cc::VideoFrameProvider::Client* client);
|
| void OnFrameAvailable();
|
|
|
| + base::Lock lock_;
|
| scoped_refptr<base::MessageLoopProxy> loop_;
|
| - base::Lock client_lock_;
|
| cc::VideoFrameProvider::Client* client_;
|
| - base::Closure callback_;
|
|
|
| + // Accessed on the |loop_| thread only.
|
| + base::Closure callback_;
|
| scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
|
| context_provider_;
|
| scoped_refptr<gfx::SurfaceTexture> surface_texture_;
|
| -
|
| float current_matrix_[16];
|
| bool has_updated_;
|
|
|
| @@ -58,27 +60,58 @@ class StreamTextureProxyImpl
|
|
|
| StreamTextureProxyImpl::StreamTextureProxyImpl(
|
| StreamTextureFactorySynchronousImpl::ContextProvider* provider)
|
| - : context_provider_(provider), has_updated_(false) {
|
| + : client_(NULL), context_provider_(provider), has_updated_(false) {
|
| std::fill(current_matrix_, current_matrix_ + 16, 0);
|
| }
|
|
|
| StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
|
|
|
| void StreamTextureProxyImpl::Release() {
|
| - SetClient(NULL);
|
| - if (loop_.get() && !loop_->BelongsToCurrentThread())
|
| - loop_->DeleteSoon(FROM_HERE, this);
|
| - else
|
| + base::AutoLock lock(lock_);
|
| + client_ = NULL;
|
| + if (!loop_.get() || loop_.get() != base::MessageLoopProxy::current() ||
|
| + !loop_->DeleteSoon(FROM_HERE, this)) {
|
| delete this;
|
| + }
|
| }
|
|
|
| -void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) {
|
| - base::AutoLock lock(client_lock_);
|
| - client_ = client;
|
| +void StreamTextureProxyImpl::Bind(int32 stream_id,
|
| + cc::VideoFrameProvider::Client* client,
|
| + scoped_refptr<base::MessageLoopProxy> loop) {
|
| + base::AutoLock lock(lock_);
|
| + DCHECK(loop.get());
|
| + loop_ = loop;
|
| +
|
| + if (loop.get() != base::MessageLoopProxy::current()) {
|
| + // Unretained is safe here only because the object is deleted on |loop_|
|
| + // thread.
|
| + loop->PostTask(FROM_HERE,
|
| + base::Bind(&StreamTextureProxyImpl::BindOnThread,
|
| + base::Unretained(this),
|
| + stream_id,
|
| + client));
|
| + } else {
|
| + client_ = client;
|
| + surface_texture_ = context_provider_->GetSurfaceTexture(stream_id);
|
| + if (!surface_texture_) {
|
| + LOG(ERROR) << "Failed to get SurfaceTexture for stream.";
|
| + return;
|
| + }
|
| +
|
| + callback_ =
|
| + base::Bind(&StreamTextureProxyImpl::OnFrameAvailable, AsWeakPtr());
|
| + surface_texture_->SetFrameAvailableCallback(callback_);
|
| + }
|
| }
|
|
|
| -void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) {
|
| - loop_ = base::MessageLoopProxy::current();
|
| +void StreamTextureProxyImpl::BindOnThread(
|
| + int32 stream_id,
|
| + cc::VideoFrameProvider::Client* client) {
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + client_ = client;
|
| + }
|
| +
|
| surface_texture_ = context_provider_->GetSurfaceTexture(stream_id);
|
| if (!surface_texture_) {
|
| LOG(ERROR) << "Failed to get SurfaceTexture for stream.";
|
| @@ -101,7 +134,7 @@ void StreamTextureProxyImpl::OnFrameAvailable() {
|
| if (memcmp(current_matrix_, matrix, sizeof(matrix)) != 0) {
|
| memcpy(current_matrix_, matrix, sizeof(matrix));
|
|
|
| - base::AutoLock lock(client_lock_);
|
| + base::AutoLock lock(lock_);
|
| if (client_)
|
| client_->DidUpdateMatrix(current_matrix_);
|
| }
|
| @@ -110,7 +143,7 @@ void StreamTextureProxyImpl::OnFrameAvailable() {
|
| // updateTexImage since after we received the first frame.
|
| has_updated_ = true;
|
|
|
| - base::AutoLock lock(client_lock_);
|
| + base::AutoLock lock(lock_);
|
| if (client_)
|
| client_->DidReceiveFrame();
|
| }
|
| @@ -182,4 +215,14 @@ gpu::gles2::GLES2Interface* StreamTextureFactorySynchronousImpl::ContextGL() {
|
| return context_provider_->ContextGL();
|
| }
|
|
|
| +void StreamTextureFactorySynchronousImpl::AddObserver(
|
| + StreamTextureFactoryContextObserver* obs) {
|
| + context_provider_->AddObserver(obs);
|
| +}
|
| +
|
| +void StreamTextureFactorySynchronousImpl::RemoveObserver(
|
| + StreamTextureFactoryContextObserver* obs) {
|
| + context_provider_->RemoveObserver(obs);
|
| +}
|
| +
|
| } // namespace content
|
|
|