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 |