OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/plugins/ppapi/ppb_video_decoder_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_video_decoder_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 using ppapi::thunk::PPB_Context3D_API; | 29 using ppapi::thunk::PPB_Context3D_API; |
30 using ppapi::thunk::PPB_VideoDecoder_API; | 30 using ppapi::thunk::PPB_VideoDecoder_API; |
31 | 31 |
32 namespace webkit { | 32 namespace webkit { |
33 namespace ppapi { | 33 namespace ppapi { |
34 | 34 |
35 PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance) | 35 PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance) |
36 : Resource(instance), | 36 : Resource(instance), |
37 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 37 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
38 context3d_id_(0), | 38 context3d_id_(0), |
39 destroy_callback_(PP_BlockUntilComplete()), | |
40 flush_callback_(PP_BlockUntilComplete()), | 39 flush_callback_(PP_BlockUntilComplete()), |
41 reset_callback_(PP_BlockUntilComplete()) { | 40 reset_callback_(PP_BlockUntilComplete()) { |
42 ppp_videodecoder_ = | 41 ppp_videodecoder_ = |
43 static_cast<const PPP_VideoDecoder_Dev*>(instance->module()-> | 42 static_cast<const PPP_VideoDecoder_Dev*>(instance->module()-> |
44 GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE)); | 43 GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE)); |
45 } | 44 } |
46 | 45 |
47 PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { | 46 PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { |
48 if (context3d_id_) | 47 if (context3d_id_) |
49 ResourceTracker::Get()->UnrefResource(context3d_id_); | 48 ResourceTracker::Get()->UnrefResource(context3d_id_); |
(...skipping 19 matching lines...) Expand all Loading... |
69 PPB_Context3D_Impl* context3d = | 68 PPB_Context3D_Impl* context3d = |
70 static_cast<PPB_Context3D_Impl*>(enter.object()); | 69 static_cast<PPB_Context3D_Impl*>(enter.object()); |
71 | 70 |
72 context3d_id_ = context_id; | 71 context3d_id_ = context_id; |
73 ResourceTracker::Get()->AddRefResource(context3d_id_); | 72 ResourceTracker::Get()->AddRefResource(context3d_id_); |
74 int command_buffer_route_id = | 73 int command_buffer_route_id = |
75 context3d->platform_context()->GetCommandBufferRouteId(); | 74 context3d->platform_context()->GetCommandBufferRouteId(); |
76 if (command_buffer_route_id == 0) | 75 if (command_buffer_route_id == 0) |
77 return PP_ERROR_FAILED; | 76 return PP_ERROR_FAILED; |
78 | 77 |
79 platform_video_decoder_.reset( | 78 platform_video_decoder_ = instance()->delegate()->CreateVideoDecoder( |
80 instance()->delegate()->CreateVideoDecoder( | 79 this, command_buffer_route_id, context3d->gles2_impl()->helper()); |
81 this, command_buffer_route_id, context3d->gles2_impl()->helper())); | |
82 | 80 |
83 if (!platform_video_decoder_.get()) | 81 if (!platform_video_decoder_) |
84 return PP_ERROR_FAILED; | 82 return PP_ERROR_FAILED; |
85 | 83 |
86 std::vector<uint32> copied; | 84 std::vector<uint32> copied; |
87 // TODO(fischman,vrk): this is completely broken in that it fails to account | 85 // TODO(fischman,vrk): this is completely broken in that it fails to account |
88 // for the semantic distinction between keys and values; it is certainly | 86 // for the semantic distinction between keys and values; it is certainly |
89 // possible for a value to show up as 0, and that shouldn't terminate the | 87 // possible for a value to show up as 0, and that shouldn't terminate the |
90 // config vector. Only a *key* of 0 should do so. | 88 // config vector. Only a *key* of 0 should do so. |
91 // TODO(vrk): This is assuming PP_VideoAttributeDictionary and | 89 // TODO(vrk): This is assuming PP_VideoAttributeDictionary and |
92 // VideoAttributeKey have identical enum values. There is no compiler | 90 // VideoAttributeKey have identical enum values. There is no compiler |
93 // assert to guarantee this. We either need to add such asserts or | 91 // assert to guarantee this. We either need to add such asserts or |
94 // merge PP_VideoAttributeDictionary and VideoAttributeKey. | 92 // merge PP_VideoAttributeDictionary and VideoAttributeKey. |
95 for (const PP_VideoConfigElement* current = decoder_config; | 93 for (const PP_VideoConfigElement* current = decoder_config; |
96 *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR; ++current) { | 94 *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR; ++current) { |
97 copied.push_back(static_cast<uint32>(*current)); | 95 copied.push_back(static_cast<uint32>(*current)); |
98 } | 96 } |
99 | 97 |
100 if (platform_video_decoder_->Initialize(copied)) { | 98 if (platform_video_decoder_->Initialize(copied)) { |
101 initialization_callback_ = callback; | 99 initialization_callback_ = callback; |
102 return PP_OK_COMPLETIONPENDING; | 100 return PP_OK_COMPLETIONPENDING; |
103 } else { | 101 } else { |
104 return PP_ERROR_FAILED; | 102 return PP_ERROR_FAILED; |
105 } | 103 } |
106 } | 104 } |
107 | 105 |
108 int32_t PPB_VideoDecoder_Impl::Decode( | 106 int32_t PPB_VideoDecoder_Impl::Decode( |
109 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, | 107 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, |
110 PP_CompletionCallback callback) { | 108 PP_CompletionCallback callback) { |
111 if (!platform_video_decoder_.get()) | 109 if (!platform_video_decoder_) |
112 return PP_ERROR_BADRESOURCE; | 110 return PP_ERROR_BADRESOURCE; |
113 | 111 |
114 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); | 112 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); |
115 if (enter.failed()) | 113 if (enter.failed()) |
116 return PP_ERROR_FAILED; | 114 return PP_ERROR_FAILED; |
117 | 115 |
118 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); | 116 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); |
119 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, | 117 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, |
120 buffer->shared_memory()->handle(), | 118 buffer->shared_memory()->handle(), |
121 static_cast<size_t>(buffer->size())); | 119 static_cast<size_t>(buffer->size())); |
122 CHECK(bitstream_buffer_callbacks_.insert(std::make_pair( | 120 CHECK(bitstream_buffer_callbacks_.insert(std::make_pair( |
123 bitstream_buffer->id, callback)).second); | 121 bitstream_buffer->id, callback)).second); |
124 | 122 |
125 platform_video_decoder_->Decode(decode_buffer); | 123 platform_video_decoder_->Decode(decode_buffer); |
126 return PP_OK_COMPLETIONPENDING; | 124 return PP_OK_COMPLETIONPENDING; |
127 } | 125 } |
128 | 126 |
129 void PPB_VideoDecoder_Impl::AssignGLESBuffers( | 127 void PPB_VideoDecoder_Impl::AssignGLESBuffers( |
130 uint32_t no_of_buffers, | 128 uint32_t no_of_buffers, |
131 const PP_GLESBuffer_Dev* buffers) { | 129 const PP_GLESBuffer_Dev* buffers) { |
132 if (!platform_video_decoder_.get()) | 130 if (!platform_video_decoder_) |
133 return; | 131 return; |
134 | 132 |
135 std::vector<media::GLESBuffer> wrapped_buffers; | 133 std::vector<media::GLESBuffer> wrapped_buffers; |
136 for (uint32 i = 0; i < no_of_buffers; i++) { | 134 for (uint32 i = 0; i < no_of_buffers; i++) { |
137 PP_GLESBuffer_Dev in_buf = buffers[i]; | 135 PP_GLESBuffer_Dev in_buf = buffers[i]; |
138 media::GLESBuffer buffer( | 136 media::GLESBuffer buffer( |
139 in_buf.info.id, | 137 in_buf.info.id, |
140 gfx::Size(in_buf.info.size.width, in_buf.info.size.height), | 138 gfx::Size(in_buf.info.size.width, in_buf.info.size.height), |
141 in_buf.texture_id); | 139 in_buf.texture_id); |
142 wrapped_buffers.push_back(buffer); | 140 wrapped_buffers.push_back(buffer); |
143 } | 141 } |
144 platform_video_decoder_->AssignGLESBuffers(wrapped_buffers); | 142 platform_video_decoder_->AssignGLESBuffers(wrapped_buffers); |
145 } | 143 } |
146 | 144 |
147 void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { | 145 void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { |
148 if (!platform_video_decoder_.get()) | 146 if (!platform_video_decoder_) |
149 return; | 147 return; |
150 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); | 148 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); |
151 } | 149 } |
152 | 150 |
153 int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { | 151 int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { |
154 if (!platform_video_decoder_.get()) | 152 if (!platform_video_decoder_) |
155 return PP_ERROR_BADRESOURCE; | 153 return PP_ERROR_BADRESOURCE; |
156 | 154 |
157 // Store the callback to be called when Flush() is done. | 155 // Store the callback to be called when Flush() is done. |
158 // TODO(fischman,vrk): consider implications of already-outstanding callback. | 156 // TODO(fischman,vrk): consider implications of already-outstanding callback. |
159 flush_callback_ = callback; | 157 flush_callback_ = callback; |
160 | 158 |
161 platform_video_decoder_->Flush(); | 159 platform_video_decoder_->Flush(); |
162 return PP_OK_COMPLETIONPENDING; | 160 return PP_OK_COMPLETIONPENDING; |
163 } | 161 } |
164 | 162 |
165 int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) { | 163 int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) { |
166 if (!platform_video_decoder_.get()) | 164 if (!platform_video_decoder_) |
167 return PP_ERROR_BADRESOURCE; | 165 return PP_ERROR_BADRESOURCE; |
168 | 166 |
169 // Store the callback to be called when Reset() is done. | 167 // Store the callback to be called when Reset() is done. |
170 // TODO(fischman,vrk): consider implications of already-outstanding callback. | 168 // TODO(fischman,vrk): consider implications of already-outstanding callback. |
171 reset_callback_ = callback; | 169 reset_callback_ = callback; |
172 | 170 |
173 platform_video_decoder_->Reset(); | 171 platform_video_decoder_->Reset(); |
174 return PP_OK_COMPLETIONPENDING; | 172 return PP_OK_COMPLETIONPENDING; |
175 } | 173 } |
176 | 174 |
177 int32_t PPB_VideoDecoder_Impl::Destroy(PP_CompletionCallback callback) { | 175 void PPB_VideoDecoder_Impl::Destroy() { |
178 if (!platform_video_decoder_.get()) | 176 if (!platform_video_decoder_) |
179 return PP_ERROR_BADRESOURCE; | 177 return; |
180 | |
181 // Store the callback to be called when Destroy() is done. | |
182 // TODO(fischman,vrk): consider implications of already-outstanding callback. | |
183 destroy_callback_ = callback; | |
184 | |
185 platform_video_decoder_->Destroy(); | 178 platform_video_decoder_->Destroy(); |
186 return PP_OK_COMPLETIONPENDING; | |
187 } | 179 } |
188 | 180 |
189 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( | 181 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( |
190 uint32 requested_num_of_buffers, | 182 uint32 requested_num_of_buffers, |
191 const gfx::Size& dimensions, | 183 const gfx::Size& dimensions, |
192 media::VideoDecodeAccelerator::MemoryType type) { | 184 media::VideoDecodeAccelerator::MemoryType type) { |
193 if (!ppp_videodecoder_) | 185 if (!ppp_videodecoder_) |
194 return; | 186 return; |
195 | 187 |
196 // TODO(vrk): Compiler assert or use switch statement instead of making | 188 // TODO(vrk): Compiler assert or use switch statement instead of making |
197 // a blind cast. | 189 // a blind cast. |
198 PP_PictureBufferType_Dev out_type = | 190 PP_PictureBufferType_Dev out_type = |
199 static_cast<PP_PictureBufferType_Dev>(type); | 191 static_cast<PP_PictureBufferType_Dev>(type); |
200 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); | 192 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); |
201 ScopedResourceId resource(this); | |
202 ppp_videodecoder_->ProvidePictureBuffers( | 193 ppp_videodecoder_->ProvidePictureBuffers( |
203 instance()->pp_instance(), resource.id, requested_num_of_buffers, | 194 instance()->pp_instance(), requested_num_of_buffers, out_dim, out_type); |
204 out_dim, out_type); | |
205 } | 195 } |
206 | 196 |
207 void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { | 197 void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { |
208 if (!ppp_videodecoder_) | 198 if (!ppp_videodecoder_) |
209 return; | 199 return; |
210 | 200 |
211 ScopedResourceId resource(this); | |
212 PP_Picture_Dev output; | 201 PP_Picture_Dev output; |
213 output.picture_buffer_id = picture.picture_buffer_id(); | 202 output.picture_buffer_id = picture.picture_buffer_id(); |
214 output.bitstream_buffer_id = picture.bitstream_buffer_id(); | 203 output.bitstream_buffer_id = picture.bitstream_buffer_id(); |
215 output.visible_size = PP_MakeSize(picture.visible_size().width(), | 204 output.visible_size = PP_MakeSize(picture.visible_size().width(), |
216 picture.visible_size().height()); | 205 picture.visible_size().height()); |
217 output.decoded_size = PP_MakeSize(picture.decoded_size().width(), | 206 output.decoded_size = PP_MakeSize(picture.decoded_size().width(), |
218 picture.decoded_size().height()); | 207 picture.decoded_size().height()); |
219 ppp_videodecoder_->PictureReady( | 208 ppp_videodecoder_->PictureReady(instance()->pp_instance(), output); |
220 instance()->pp_instance(), resource.id, output); | |
221 } | 209 } |
222 | 210 |
223 void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { | 211 void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { |
224 if (!ppp_videodecoder_) | 212 if (!ppp_videodecoder_) |
225 return; | 213 return; |
226 | 214 |
227 ScopedResourceId resource(this); | |
228 ppp_videodecoder_->DismissPictureBuffer( | 215 ppp_videodecoder_->DismissPictureBuffer( |
229 instance()->pp_instance(), resource.id, picture_buffer_id); | 216 instance()->pp_instance(), picture_buffer_id); |
230 } | 217 } |
231 | 218 |
232 void PPB_VideoDecoder_Impl::NotifyEndOfStream() { | 219 void PPB_VideoDecoder_Impl::NotifyEndOfStream() { |
233 if (!ppp_videodecoder_) | 220 if (!ppp_videodecoder_) |
234 return; | 221 return; |
235 | 222 |
236 ScopedResourceId resource(this); | 223 ppp_videodecoder_->EndOfStream(instance()->pp_instance()); |
237 ppp_videodecoder_->EndOfStream(instance()->pp_instance(), resource.id); | |
238 } | 224 } |
239 | 225 |
240 void PPB_VideoDecoder_Impl::NotifyError( | 226 void PPB_VideoDecoder_Impl::NotifyError( |
241 media::VideoDecodeAccelerator::Error error) { | 227 media::VideoDecodeAccelerator::Error error) { |
242 if (!ppp_videodecoder_) | 228 if (!ppp_videodecoder_) |
243 return; | 229 return; |
244 | 230 |
245 ScopedResourceId resource(this); | |
246 // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and | 231 // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and |
247 // PP_VideoDecodeError_Dev have identical enum values. There is no compiler | 232 // PP_VideoDecodeError_Dev have identical enum values. There is no compiler |
248 // assert to guarantee this. We either need to add such asserts or | 233 // assert to guarantee this. We either need to add such asserts or |
249 // merge these two enums. | 234 // merge these two enums. |
250 ppp_videodecoder_->NotifyError(instance()->pp_instance(), resource.id, | 235 ppp_videodecoder_->NotifyError(instance()->pp_instance(), |
251 static_cast<PP_VideoDecodeError_Dev>(error)); | 236 static_cast<PP_VideoDecodeError_Dev>(error)); |
252 } | 237 } |
253 | 238 |
254 void PPB_VideoDecoder_Impl::NotifyResetDone() { | 239 void PPB_VideoDecoder_Impl::NotifyResetDone() { |
255 if (reset_callback_.func == NULL) | 240 if (reset_callback_.func == NULL) |
256 return; | 241 return; |
257 | 242 |
258 // Call the callback that was stored to be called when Reset is done. | 243 // Call the callback that was stored to be called when Reset is done. |
259 PP_RunAndClearCompletionCallback(&reset_callback_, PP_OK); | 244 PP_RunAndClearCompletionCallback(&reset_callback_, PP_OK); |
260 } | 245 } |
261 | 246 |
262 void PPB_VideoDecoder_Impl::NotifyDestroyDone() { | |
263 if (destroy_callback_.func == NULL) | |
264 return; | |
265 | |
266 // Call the callback that was stored to be called when Destroy is done. | |
267 PP_RunAndClearCompletionCallback(&destroy_callback_, PP_OK); | |
268 } | |
269 | |
270 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( | 247 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( |
271 int32 bitstream_buffer_id) { | 248 int32 bitstream_buffer_id) { |
272 CallbackById::iterator it = | 249 CallbackById::iterator it = |
273 bitstream_buffer_callbacks_.find(bitstream_buffer_id); | 250 bitstream_buffer_callbacks_.find(bitstream_buffer_id); |
274 DCHECK(it != bitstream_buffer_callbacks_.end()); | 251 DCHECK(it != bitstream_buffer_callbacks_.end()); |
275 PP_CompletionCallback cc = it->second; | 252 PP_CompletionCallback cc = it->second; |
276 bitstream_buffer_callbacks_.erase(it); | 253 bitstream_buffer_callbacks_.erase(it); |
277 PP_RunCompletionCallback(&cc, PP_OK); | 254 PP_RunCompletionCallback(&cc, PP_OK); |
278 } | 255 } |
279 | 256 |
280 void PPB_VideoDecoder_Impl::NotifyFlushDone() { | 257 void PPB_VideoDecoder_Impl::NotifyFlushDone() { |
281 if (flush_callback_.func == NULL) | 258 if (flush_callback_.func == NULL) |
282 return; | 259 return; |
283 | 260 |
284 // Call the callback that was stored to be called when Flush is done. | 261 // Call the callback that was stored to be called when Flush is done. |
285 PP_RunAndClearCompletionCallback(&flush_callback_, PP_OK); | 262 PP_RunAndClearCompletionCallback(&flush_callback_, PP_OK); |
286 } | 263 } |
287 | 264 |
288 void PPB_VideoDecoder_Impl::NotifyInitializeDone() { | 265 void PPB_VideoDecoder_Impl::NotifyInitializeDone() { |
289 if (initialization_callback_.func == NULL) | 266 if (initialization_callback_.func == NULL) |
290 return; | 267 return; |
291 | 268 |
292 PP_RunAndClearCompletionCallback(&initialization_callback_, PP_OK); | 269 PP_RunAndClearCompletionCallback(&initialization_callback_, PP_OK); |
293 } | 270 } |
294 | 271 |
295 } // namespace ppapi | 272 } // namespace ppapi |
296 } // namespace webkit | 273 } // namespace webkit |
OLD | NEW |