OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/pepper/ppb_video_decoder_impl.h" | 5 #include "content/renderer/pepper/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/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "content/renderer/media/pepper_platform_video_decoder.h" | 12 #include "content/common/gpu/client/gpu_channel_host.h" |
13 #include "content/renderer/pepper/common.h" | 13 #include "content/renderer/pepper/common.h" |
14 #include "content/renderer/pepper/host_globals.h" | 14 #include "content/renderer/pepper/host_globals.h" |
15 #include "content/renderer/pepper/pepper_platform_context_3d.h" | 15 #include "content/renderer/pepper/pepper_platform_context_3d.h" |
16 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 16 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
17 #include "content/renderer/pepper/plugin_module.h" | 17 #include "content/renderer/pepper/plugin_module.h" |
18 #include "content/renderer/pepper/ppb_buffer_impl.h" | 18 #include "content/renderer/pepper/ppb_buffer_impl.h" |
19 #include "content/renderer/pepper/ppb_graphics_3d_impl.h" | 19 #include "content/renderer/pepper/ppb_graphics_3d_impl.h" |
| 20 #include "content/renderer/render_thread_impl.h" |
20 #include "gpu/command_buffer/client/gles2_implementation.h" | 21 #include "gpu/command_buffer/client/gles2_implementation.h" |
21 #include "media/video/picture.h" | 22 #include "media/video/picture.h" |
22 #include "media/video/video_decode_accelerator.h" | 23 #include "media/video/video_decode_accelerator.h" |
23 #include "ppapi/c/dev/pp_video_dev.h" | 24 #include "ppapi/c/dev/pp_video_dev.h" |
24 #include "ppapi/c/dev/ppb_video_decoder_dev.h" | 25 #include "ppapi/c/dev/ppb_video_decoder_dev.h" |
25 #include "ppapi/c/dev/ppp_video_decoder_dev.h" | 26 #include "ppapi/c/dev/ppp_video_decoder_dev.h" |
26 #include "ppapi/c/pp_completion_callback.h" | 27 #include "ppapi/c/pp_completion_callback.h" |
27 #include "ppapi/c/pp_errors.h" | 28 #include "ppapi/c/pp_errors.h" |
28 #include "ppapi/shared_impl/resource_tracker.h" | 29 #include "ppapi/shared_impl/resource_tracker.h" |
29 #include "ppapi/thunk/enter.h" | 30 #include "ppapi/thunk/enter.h" |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 bool PPB_VideoDecoder_Impl::Init(PP_Resource graphics_context, | 131 bool PPB_VideoDecoder_Impl::Init(PP_Resource graphics_context, |
131 PlatformContext3D* context, | 132 PlatformContext3D* context, |
132 gpu::gles2::GLES2Implementation* gles2_impl, | 133 gpu::gles2::GLES2Implementation* gles2_impl, |
133 PP_VideoDecoder_Profile profile) { | 134 PP_VideoDecoder_Profile profile) { |
134 InitCommon(graphics_context, gles2_impl); | 135 InitCommon(graphics_context, gles2_impl); |
135 | 136 |
136 int command_buffer_route_id = context->GetCommandBufferRouteId(); | 137 int command_buffer_route_id = context->GetCommandBufferRouteId(); |
137 if (command_buffer_route_id == 0) | 138 if (command_buffer_route_id == 0) |
138 return false; | 139 return false; |
139 | 140 |
140 platform_video_decoder_.reset( | 141 FlushCommandBuffer(); |
141 new PlatformVideoDecoder(command_buffer_route_id)); | 142 |
142 if (!platform_video_decoder_) | 143 RenderThreadImpl* render_thread = RenderThreadImpl::current(); |
| 144 |
| 145 // This is not synchronous, but subsequent IPC messages will be buffered, so |
| 146 // it is okay to immediately send IPC messages through the returned channel. |
| 147 GpuChannelHost* channel = |
| 148 render_thread->EstablishGpuChannelSync( |
| 149 CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE); |
| 150 |
| 151 if (!channel) |
143 return false; | 152 return false; |
144 | 153 |
145 FlushCommandBuffer(); | 154 decoder_ = channel->CreateVideoDecoder(command_buffer_route_id); |
146 return platform_video_decoder_->Initialize(PPToMediaProfile(profile), this); | 155 return (decoder_ && decoder_->Initialize(PPToMediaProfile(profile), this)); |
147 } | 156 } |
148 | 157 |
149 int32_t PPB_VideoDecoder_Impl::Decode( | 158 int32_t PPB_VideoDecoder_Impl::Decode( |
150 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, | 159 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, |
151 scoped_refptr<TrackedCallback> callback) { | 160 scoped_refptr<TrackedCallback> callback) { |
152 if (!platform_video_decoder_) | 161 if (!decoder_) |
153 return PP_ERROR_BADRESOURCE; | 162 return PP_ERROR_BADRESOURCE; |
154 | 163 |
155 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); | 164 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); |
156 if (enter.failed()) | 165 if (enter.failed()) |
157 return PP_ERROR_FAILED; | 166 return PP_ERROR_FAILED; |
158 | 167 |
159 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); | 168 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); |
160 DCHECK_GE(bitstream_buffer->id, 0); | 169 DCHECK_GE(bitstream_buffer->id, 0); |
161 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, | 170 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, |
162 buffer->shared_memory()->handle(), | 171 buffer->shared_memory()->handle(), |
163 bitstream_buffer->size); | 172 bitstream_buffer->size); |
164 if (!SetBitstreamBufferCallback(bitstream_buffer->id, callback)) | 173 if (!SetBitstreamBufferCallback(bitstream_buffer->id, callback)) |
165 return PP_ERROR_BADARGUMENT; | 174 return PP_ERROR_BADARGUMENT; |
166 | 175 |
167 FlushCommandBuffer(); | 176 FlushCommandBuffer(); |
168 platform_video_decoder_->Decode(decode_buffer); | 177 decoder_->Decode(decode_buffer); |
169 return PP_OK_COMPLETIONPENDING; | 178 return PP_OK_COMPLETIONPENDING; |
170 } | 179 } |
171 | 180 |
172 void PPB_VideoDecoder_Impl::AssignPictureBuffers( | 181 void PPB_VideoDecoder_Impl::AssignPictureBuffers( |
173 uint32_t no_of_buffers, | 182 uint32_t no_of_buffers, |
174 const PP_PictureBuffer_Dev* buffers) { | 183 const PP_PictureBuffer_Dev* buffers) { |
175 if (!platform_video_decoder_) | 184 if (!decoder_) |
176 return; | 185 return; |
177 UMA_HISTOGRAM_COUNTS_100("Media.PepperVideoDecoderPictureCount", | 186 UMA_HISTOGRAM_COUNTS_100("Media.PepperVideoDecoderPictureCount", |
178 no_of_buffers); | 187 no_of_buffers); |
179 | 188 |
180 std::vector<media::PictureBuffer> wrapped_buffers; | 189 std::vector<media::PictureBuffer> wrapped_buffers; |
181 for (uint32 i = 0; i < no_of_buffers; i++) { | 190 for (uint32 i = 0; i < no_of_buffers; i++) { |
182 PP_PictureBuffer_Dev in_buf = buffers[i]; | 191 PP_PictureBuffer_Dev in_buf = buffers[i]; |
183 DCHECK_GE(in_buf.id, 0); | 192 DCHECK_GE(in_buf.id, 0); |
184 media::PictureBuffer buffer( | 193 media::PictureBuffer buffer( |
185 in_buf.id, | 194 in_buf.id, |
186 gfx::Size(in_buf.size.width, in_buf.size.height), | 195 gfx::Size(in_buf.size.width, in_buf.size.height), |
187 in_buf.texture_id); | 196 in_buf.texture_id); |
188 wrapped_buffers.push_back(buffer); | 197 wrapped_buffers.push_back(buffer); |
189 UMA_HISTOGRAM_COUNTS_10000("Media.PepperVideoDecoderPictureHeight", | 198 UMA_HISTOGRAM_COUNTS_10000("Media.PepperVideoDecoderPictureHeight", |
190 in_buf.size.height); | 199 in_buf.size.height); |
191 } | 200 } |
192 | 201 |
193 FlushCommandBuffer(); | 202 FlushCommandBuffer(); |
194 platform_video_decoder_->AssignPictureBuffers(wrapped_buffers); | 203 decoder_->AssignPictureBuffers(wrapped_buffers); |
195 } | 204 } |
196 | 205 |
197 void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { | 206 void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { |
198 if (!platform_video_decoder_) | 207 if (!decoder_) |
199 return; | 208 return; |
200 | 209 |
201 FlushCommandBuffer(); | 210 FlushCommandBuffer(); |
202 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); | 211 decoder_->ReusePictureBuffer(picture_buffer_id); |
203 } | 212 } |
204 | 213 |
205 int32_t PPB_VideoDecoder_Impl::Flush(scoped_refptr<TrackedCallback> callback) { | 214 int32_t PPB_VideoDecoder_Impl::Flush(scoped_refptr<TrackedCallback> callback) { |
206 if (!platform_video_decoder_) | 215 if (!decoder_) |
207 return PP_ERROR_BADRESOURCE; | 216 return PP_ERROR_BADRESOURCE; |
208 | 217 |
209 if (!SetFlushCallback(callback)) | 218 if (!SetFlushCallback(callback)) |
210 return PP_ERROR_INPROGRESS; | 219 return PP_ERROR_INPROGRESS; |
211 | 220 |
212 FlushCommandBuffer(); | 221 FlushCommandBuffer(); |
213 platform_video_decoder_->Flush(); | 222 decoder_->Flush(); |
214 return PP_OK_COMPLETIONPENDING; | 223 return PP_OK_COMPLETIONPENDING; |
215 } | 224 } |
216 | 225 |
217 int32_t PPB_VideoDecoder_Impl::Reset(scoped_refptr<TrackedCallback> callback) { | 226 int32_t PPB_VideoDecoder_Impl::Reset(scoped_refptr<TrackedCallback> callback) { |
218 if (!platform_video_decoder_) | 227 if (!decoder_) |
219 return PP_ERROR_BADRESOURCE; | 228 return PP_ERROR_BADRESOURCE; |
220 | 229 |
221 if (!SetResetCallback(callback)) | 230 if (!SetResetCallback(callback)) |
222 return PP_ERROR_INPROGRESS; | 231 return PP_ERROR_INPROGRESS; |
223 | 232 |
224 FlushCommandBuffer(); | 233 FlushCommandBuffer(); |
225 platform_video_decoder_->Reset(); | 234 decoder_->Reset(); |
226 return PP_OK_COMPLETIONPENDING; | 235 return PP_OK_COMPLETIONPENDING; |
227 } | 236 } |
228 | 237 |
229 void PPB_VideoDecoder_Impl::Destroy() { | 238 void PPB_VideoDecoder_Impl::Destroy() { |
230 FlushCommandBuffer(); | 239 FlushCommandBuffer(); |
231 | 240 |
232 if (platform_video_decoder_) | 241 if (decoder_) |
233 platform_video_decoder_.release()->Destroy(); | 242 decoder_.release()->Destroy(); |
234 ppp_videodecoder_ = NULL; | 243 ppp_videodecoder_ = NULL; |
235 | 244 |
236 ::ppapi::PPB_VideoDecoder_Shared::Destroy(); | 245 ::ppapi::PPB_VideoDecoder_Shared::Destroy(); |
237 } | 246 } |
238 | 247 |
239 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( | 248 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( |
240 uint32 requested_num_of_buffers, | 249 uint32 requested_num_of_buffers, |
241 const gfx::Size& dimensions, | 250 const gfx::Size& dimensions, |
242 uint32 texture_target) { | 251 uint32 texture_target) { |
| 252 DCHECK(RenderThreadImpl::current()); |
243 if (!ppp_videodecoder_) | 253 if (!ppp_videodecoder_) |
244 return; | 254 return; |
245 | 255 |
246 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); | 256 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); |
247 ppp_videodecoder_->ProvidePictureBuffers(pp_instance(), | 257 ppp_videodecoder_->ProvidePictureBuffers(pp_instance(), |
248 pp_resource(), | 258 pp_resource(), |
249 requested_num_of_buffers, | 259 requested_num_of_buffers, |
250 &out_dim, | 260 &out_dim, |
251 texture_target); | 261 texture_target); |
252 } | 262 } |
253 | 263 |
254 void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { | 264 void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { |
| 265 DCHECK(RenderThreadImpl::current()); |
255 if (!ppp_videodecoder_) | 266 if (!ppp_videodecoder_) |
256 return; | 267 return; |
257 | 268 |
258 PP_Picture_Dev output; | 269 PP_Picture_Dev output; |
259 output.picture_buffer_id = picture.picture_buffer_id(); | 270 output.picture_buffer_id = picture.picture_buffer_id(); |
260 output.bitstream_buffer_id = picture.bitstream_buffer_id(); | 271 output.bitstream_buffer_id = picture.bitstream_buffer_id(); |
261 ppp_videodecoder_->PictureReady(pp_instance(), pp_resource(), &output); | 272 ppp_videodecoder_->PictureReady(pp_instance(), pp_resource(), &output); |
262 } | 273 } |
263 | 274 |
264 void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { | 275 void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { |
| 276 DCHECK(RenderThreadImpl::current()); |
265 if (!ppp_videodecoder_) | 277 if (!ppp_videodecoder_) |
266 return; | 278 return; |
267 ppp_videodecoder_->DismissPictureBuffer( | 279 ppp_videodecoder_->DismissPictureBuffer( |
268 pp_instance(), pp_resource(), picture_buffer_id); | 280 pp_instance(), pp_resource(), picture_buffer_id); |
269 } | 281 } |
270 | 282 |
271 void PPB_VideoDecoder_Impl::NotifyError( | 283 void PPB_VideoDecoder_Impl::NotifyError( |
272 media::VideoDecodeAccelerator::Error error) { | 284 media::VideoDecodeAccelerator::Error error) { |
| 285 DCHECK(RenderThreadImpl::current()); |
273 if (!ppp_videodecoder_) | 286 if (!ppp_videodecoder_) |
274 return; | 287 return; |
275 | 288 |
276 PP_VideoDecodeError_Dev pp_error = MediaToPPError(error); | 289 PP_VideoDecodeError_Dev pp_error = MediaToPPError(error); |
277 ppp_videodecoder_->NotifyError(pp_instance(), pp_resource(), pp_error); | 290 ppp_videodecoder_->NotifyError(pp_instance(), pp_resource(), pp_error); |
278 UMA_HISTOGRAM_ENUMERATION("Media.PepperVideoDecoderError", | 291 UMA_HISTOGRAM_ENUMERATION("Media.PepperVideoDecoderError", |
279 error, | 292 error, |
280 media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM); | 293 media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM); |
281 } | 294 } |
282 | 295 |
283 void PPB_VideoDecoder_Impl::NotifyResetDone() { RunResetCallback(PP_OK); } | 296 void PPB_VideoDecoder_Impl::NotifyResetDone() { |
| 297 DCHECK(RenderThreadImpl::current()); |
| 298 RunResetCallback(PP_OK); |
| 299 } |
284 | 300 |
285 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( | 301 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( |
286 int32 bitstream_buffer_id) { | 302 int32 bitstream_buffer_id) { |
| 303 DCHECK(RenderThreadImpl::current()); |
287 RunBitstreamBufferCallback(bitstream_buffer_id, PP_OK); | 304 RunBitstreamBufferCallback(bitstream_buffer_id, PP_OK); |
288 } | 305 } |
289 | 306 |
290 void PPB_VideoDecoder_Impl::NotifyFlushDone() { RunFlushCallback(PP_OK); } | 307 void PPB_VideoDecoder_Impl::NotifyFlushDone() { |
| 308 DCHECK(RenderThreadImpl::current()); |
| 309 RunFlushCallback(PP_OK); |
| 310 } |
291 | 311 |
292 } // namespace content | 312 } // namespace content |
OLD | NEW |