Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Side by Side Diff: content/renderer/pepper/pepper_video_decoder_host.cc

Issue 311853005: Implement software fallback for PPB_VideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase, fix Windows compile, restore test. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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/pepper_video_decoder_host.h" 5 #include "content/renderer/pepper/pepper_video_decoder_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/shared_memory.h" 8 #include "base/memory/shared_memory.h"
9 #include "content/common/gpu/client/gpu_channel_host.h" 9 #include "content/common/gpu/client/gpu_channel_host.h"
10 #include "content/public/renderer/render_thread.h" 10 #include "content/public/renderer/render_thread.h"
11 #include "content/public/renderer/renderer_ppapi_host.h" 11 #include "content/public/renderer/renderer_ppapi_host.h"
12 #include "content/renderer/pepper/ppb_graphics_3d_impl.h" 12 #include "content/renderer/pepper/ppb_graphics_3d_impl.h"
13 #include "content/renderer/render_thread_impl.h" 13 #include "content/renderer/pepper/video_decoder_shim.h"
14 #include "content/renderer/render_view_impl.h"
15 #include "media/video/picture.h"
16 #include "media/video/video_decode_accelerator.h" 14 #include "media/video/video_decode_accelerator.h"
17 #include "ppapi/c/pp_completion_callback.h" 15 #include "ppapi/c/pp_completion_callback.h"
18 #include "ppapi/c/pp_errors.h" 16 #include "ppapi/c/pp_errors.h"
19 #include "ppapi/host/dispatch_host_message.h" 17 #include "ppapi/host/dispatch_host_message.h"
20 #include "ppapi/host/ppapi_host.h" 18 #include "ppapi/host/ppapi_host.h"
21 #include "ppapi/proxy/ppapi_messages.h" 19 #include "ppapi/proxy/ppapi_messages.h"
22 #include "ppapi/proxy/video_decoder_constants.h" 20 #include "ppapi/proxy/video_decoder_constants.h"
23 #include "ppapi/thunk/enter.h" 21 #include "ppapi/thunk/enter.h"
24 #include "ppapi/thunk/ppb_graphics_3d_api.h" 22 #include "ppapi/thunk/ppb_graphics_3d_api.h"
25 23
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 const ppapi::HostResource& graphics_context, 110 const ppapi::HostResource& graphics_context,
113 PP_VideoProfile profile, 111 PP_VideoProfile profile,
114 bool allow_software_fallback) { 112 bool allow_software_fallback) {
115 if (initialized_) 113 if (initialized_)
116 return PP_ERROR_FAILED; 114 return PP_ERROR_FAILED;
117 115
118 EnterResourceNoLock<PPB_Graphics3D_API> enter_graphics( 116 EnterResourceNoLock<PPB_Graphics3D_API> enter_graphics(
119 graphics_context.host_resource(), true); 117 graphics_context.host_resource(), true);
120 if (enter_graphics.failed()) 118 if (enter_graphics.failed())
121 return PP_ERROR_FAILED; 119 return PP_ERROR_FAILED;
122 graphics3d_ = static_cast<PPB_Graphics3D_Impl*>(enter_graphics.object()); 120 PPB_Graphics3D_Impl* graphics3d =
121 static_cast<PPB_Graphics3D_Impl*>(enter_graphics.object());
123 122
124 int command_buffer_route_id = graphics3d_->GetCommandBufferRouteId(); 123 int command_buffer_route_id = graphics3d->GetCommandBufferRouteId();
125 if (!command_buffer_route_id) 124 if (!command_buffer_route_id)
126 return PP_ERROR_FAILED; 125 return PP_ERROR_FAILED;
127 126
128 media::VideoCodecProfile media_profile = PepperToMediaVideoProfile(profile); 127 media::VideoCodecProfile media_profile = PepperToMediaVideoProfile(profile);
129 128
130 // This is not synchronous, but subsequent IPC messages will be buffered, so 129 // This is not synchronous, but subsequent IPC messages will be buffered, so
131 // it is okay to immediately send IPC messages through the returned channel. 130 // it is okay to immediately send IPC messages through the returned channel.
132 GpuChannelHost* channel = graphics3d_->channel(); 131 GpuChannelHost* channel = graphics3d->channel();
133 DCHECK(channel); 132 DCHECK(channel);
134 decoder_ = channel->CreateVideoDecoder(command_buffer_route_id); 133 decoder_ = channel->CreateVideoDecoder(command_buffer_route_id);
135 if (decoder_ && decoder_->Initialize(media_profile, this)) { 134 if (decoder_ && decoder_->Initialize(media_profile, this)) {
136 initialized_ = true; 135 initialized_ = true;
137 return PP_OK; 136 return PP_OK;
138 } 137 }
139 decoder_.reset(); 138 decoder_.reset();
140 139
141 // TODO(bbudge) Implement software fallback. 140 if (!allow_software_fallback)
142 return PP_ERROR_NOTSUPPORTED; 141 return PP_ERROR_NOTSUPPORTED;
142
143 decoder_.reset(new VideoDecoderShim(this));
144 initialize_reply_context_ = context->MakeReplyMessageContext();
145 decoder_->Initialize(media_profile, this);
146
147 return PP_OK_COMPLETIONPENDING;
143 } 148 }
144 149
145 int32_t PepperVideoDecoderHost::OnHostMsgGetShm( 150 int32_t PepperVideoDecoderHost::OnHostMsgGetShm(
146 ppapi::host::HostMessageContext* context, 151 ppapi::host::HostMessageContext* context,
147 uint32_t shm_id, 152 uint32_t shm_id,
148 uint32_t shm_size) { 153 uint32_t shm_size) {
149 if (!initialized_) 154 if (!initialized_)
150 return PP_ERROR_FAILED; 155 return PP_ERROR_FAILED;
151 156
152 // Make the buffers larger since we hope to reuse them. 157 // Make the buffers larger since we hope to reuse them.
(...skipping 16 matching lines...) Expand all
169 scoped_ptr<base::SharedMemory> shm( 174 scoped_ptr<base::SharedMemory> shm(
170 render_thread->HostAllocateSharedMemoryBuffer(shm_size).Pass()); 175 render_thread->HostAllocateSharedMemoryBuffer(shm_size).Pass());
171 if (!shm || !shm->Map(shm_size)) 176 if (!shm || !shm->Map(shm_size))
172 return PP_ERROR_FAILED; 177 return PP_ERROR_FAILED;
173 178
174 base::SharedMemoryHandle shm_handle = shm->handle(); 179 base::SharedMemoryHandle shm_handle = shm->handle();
175 if (shm_id == shm_buffers_.size()) { 180 if (shm_id == shm_buffers_.size()) {
176 shm_buffers_.push_back(shm.release()); 181 shm_buffers_.push_back(shm.release());
177 shm_buffer_busy_.push_back(false); 182 shm_buffer_busy_.push_back(false);
178 } else { 183 } else {
179 // Fill in the new resized buffer. Delete it manually since ScopedVector 184 // Remove the old buffer. Delete manually since ScopedVector won't delete
180 // won't delete the existing element if we just assign it. 185 // the existing element if we just assign over it.
186 shm_handle_to_memory_map_.erase(ShmIdToKey(shm_id));
181 delete shm_buffers_[shm_id]; 187 delete shm_buffers_[shm_id];
182 shm_buffers_[shm_id] = shm.release(); 188 shm_buffers_[shm_id] = shm.release();
183 } 189 }
190 shm_handle_to_memory_map_[ShmIdToKey(shm_id)] =
191 shm_buffers_[shm_id]->memory();
184 192
185 #if defined(OS_WIN) 193 #if defined(OS_WIN)
186 base::PlatformFile platform_file = shm_handle; 194 base::PlatformFile platform_file = shm_handle;
187 #elif defined(OS_POSIX) 195 #elif defined(OS_POSIX)
188 base::PlatformFile platform_file = shm_handle.fd; 196 base::PlatformFile platform_file = shm_handle.fd;
189 #else 197 #else
190 #error Not implemented. 198 #error Not implemented.
191 #endif 199 #endif
192 SerializedHandle handle( 200 SerializedHandle handle(
193 renderer_ppapi_host_->ShareHandleWithRemote(platform_file, false), 201 renderer_ppapi_host_->ShareHandleWithRemote(platform_file, false),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture( 263 int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture(
256 ppapi::host::HostMessageContext* context, 264 ppapi::host::HostMessageContext* context,
257 uint32_t texture_id) { 265 uint32_t texture_id) {
258 if (!initialized_) 266 if (!initialized_)
259 return PP_ERROR_FAILED; 267 return PP_ERROR_FAILED;
260 DCHECK(decoder_); 268 DCHECK(decoder_);
261 if (reset_reply_context_.is_valid()) 269 if (reset_reply_context_.is_valid())
262 return PP_ERROR_FAILED; 270 return PP_ERROR_FAILED;
263 271
264 decoder_->ReusePictureBuffer(texture_id); 272 decoder_->ReusePictureBuffer(texture_id);
265
266 return PP_OK; 273 return PP_OK;
267 } 274 }
268 275
269 int32_t PepperVideoDecoderHost::OnHostMsgFlush( 276 int32_t PepperVideoDecoderHost::OnHostMsgFlush(
270 ppapi::host::HostMessageContext* context) { 277 ppapi::host::HostMessageContext* context) {
271 if (!initialized_) 278 if (!initialized_)
272 return PP_ERROR_FAILED; 279 return PP_ERROR_FAILED;
273 DCHECK(decoder_); 280 DCHECK(decoder_);
274 if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) 281 if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid())
275 return PP_ERROR_FAILED; 282 return PP_ERROR_FAILED;
(...skipping 15 matching lines...) Expand all
291 reset_reply_context_ = context->MakeReplyMessageContext(); 298 reset_reply_context_ = context->MakeReplyMessageContext();
292 decoder_->Reset(); 299 decoder_->Reset();
293 300
294 return PP_OK_COMPLETIONPENDING; 301 return PP_OK_COMPLETIONPENDING;
295 } 302 }
296 303
297 void PepperVideoDecoderHost::ProvidePictureBuffers( 304 void PepperVideoDecoderHost::ProvidePictureBuffers(
298 uint32 requested_num_of_buffers, 305 uint32 requested_num_of_buffers,
299 const gfx::Size& dimensions, 306 const gfx::Size& dimensions,
300 uint32 texture_target) { 307 uint32 texture_target) {
301 DCHECK(RenderThreadImpl::current()); 308 RequestTextures(requested_num_of_buffers,
302 host()->SendUnsolicitedReply( 309 dimensions,
303 pp_resource(), 310 texture_target,
304 PpapiPluginMsg_VideoDecoder_RequestTextures( 311 std::vector<gpu::Mailbox>());
305 requested_num_of_buffers,
306 PP_MakeSize(dimensions.width(), dimensions.height()),
307 texture_target));
308 } 312 }
309 313
310 void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { 314 void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) {
311 DCHECK(RenderThreadImpl::current());
312 host()->SendUnsolicitedReply( 315 host()->SendUnsolicitedReply(
313 pp_resource(), 316 pp_resource(),
314 PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(), 317 PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(),
315 picture.picture_buffer_id())); 318 picture.picture_buffer_id()));
316 } 319 }
317 320
318 void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) { 321 void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) {
319 DCHECK(RenderThreadImpl::current());
320 host()->SendUnsolicitedReply( 322 host()->SendUnsolicitedReply(
321 pp_resource(), 323 pp_resource(),
322 PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id)); 324 PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id));
323 } 325 }
324 326
327 void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer(
328 int32 bitstream_buffer_id) {
329 PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id);
330 if (it == pending_decodes_.end()) {
331 NOTREACHED();
332 return;
333 }
334 const PendingDecode& pending_decode = it->second;
335 host()->SendReply(
336 pending_decode.reply_context,
337 PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id));
338 shm_buffer_busy_[pending_decode.shm_id] = false;
339 pending_decodes_.erase(it);
340 }
341
342 void PepperVideoDecoderHost::NotifyFlushDone() {
343 host()->SendReply(flush_reply_context_,
344 PpapiPluginMsg_VideoDecoder_FlushReply());
345 flush_reply_context_ = ppapi::host::ReplyMessageContext();
346 }
347
348 void PepperVideoDecoderHost::NotifyResetDone() {
349 host()->SendReply(reset_reply_context_,
350 PpapiPluginMsg_VideoDecoder_ResetReply());
351 reset_reply_context_ = ppapi::host::ReplyMessageContext();
352 }
353
325 void PepperVideoDecoderHost::NotifyError( 354 void PepperVideoDecoderHost::NotifyError(
326 media::VideoDecodeAccelerator::Error error) { 355 media::VideoDecodeAccelerator::Error error) {
327 DCHECK(RenderThreadImpl::current());
328 int32_t pp_error = PP_ERROR_FAILED; 356 int32_t pp_error = PP_ERROR_FAILED;
329 switch (error) { 357 switch (error) {
330 case media::VideoDecodeAccelerator::UNREADABLE_INPUT: 358 case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
331 pp_error = PP_ERROR_MALFORMED_INPUT; 359 pp_error = PP_ERROR_MALFORMED_INPUT;
332 break; 360 break;
333 case media::VideoDecodeAccelerator::ILLEGAL_STATE: 361 case media::VideoDecodeAccelerator::ILLEGAL_STATE:
334 case media::VideoDecodeAccelerator::INVALID_ARGUMENT: 362 case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
335 case media::VideoDecodeAccelerator::PLATFORM_FAILURE: 363 case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
336 case media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM: 364 case media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM:
337 pp_error = PP_ERROR_RESOURCE_FAILED; 365 pp_error = PP_ERROR_RESOURCE_FAILED;
338 break; 366 break;
339 // No default case, to catch unhandled enum values. 367 // No default case, to catch unhandled enum values.
340 } 368 }
341 host()->SendUnsolicitedReply( 369 host()->SendUnsolicitedReply(
342 pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error)); 370 pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error));
343 } 371 }
344 372
345 void PepperVideoDecoderHost::NotifyResetDone() { 373 void PepperVideoDecoderHost::OnInitializeComplete(int32_t result) {
346 DCHECK(RenderThreadImpl::current()); 374 if (!initialized_) {
347 host()->SendReply(reset_reply_context_, 375 if (result == PP_OK)
348 PpapiPluginMsg_VideoDecoder_ResetReply()); 376 initialized_ = true;
349 reset_reply_context_ = ppapi::host::ReplyMessageContext(); 377 initialize_reply_context_.params.set_result(result);
378 host()->SendReply(initialize_reply_context_,
379 PpapiPluginMsg_VideoDecoder_InitializeReply());
380 }
350 } 381 }
351 382
352 void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( 383 intptr_t PepperVideoDecoderHost::ShmIdToKey(uint32_t shm_id) {
353 int32 bitstream_buffer_id) { 384 DCHECK(shm_id < shm_buffers_.size());
354 DCHECK(RenderThreadImpl::current()); 385 return ShmHandleToKey(shm_buffers_[shm_id]->handle());
355 PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id);
356 if (it == pending_decodes_.end()) {
357 NOTREACHED();
358 return;
359 }
360 const PendingDecode& pending_decode = it->second;
361 host()->SendReply(
362 pending_decode.reply_context,
363 PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id));
364 shm_buffer_busy_[pending_decode.shm_id] = false;
365 pending_decodes_.erase(it);
366 } 386 }
367 387
368 void PepperVideoDecoderHost::NotifyFlushDone() { 388 intptr_t PepperVideoDecoderHost::ShmHandleToKey(
369 DCHECK(RenderThreadImpl::current()); 389 const base::SharedMemoryHandle& handle) {
370 host()->SendReply(flush_reply_context_, 390 #if defined(OS_WIN)
371 PpapiPluginMsg_VideoDecoder_FlushReply()); 391 return reinterpret_cast<intptr_t>(handle);
372 flush_reply_context_ = ppapi::host::ReplyMessageContext(); 392 #elif defined(OS_POSIX)
393 return handle.fd;
394 #endif
395 }
396
397 const uint8_t* PepperVideoDecoderHost::ShmHandleToAddress(
398 const base::SharedMemoryHandle& handle) {
399 SharedMemoryAddrMap::const_iterator it =
400 shm_handle_to_memory_map_.find(ShmHandleToKey(handle));
401 DCHECK(it != shm_handle_to_memory_map_.end());
402 return static_cast<uint8_t*>(it->second);
403 }
404
405 void PepperVideoDecoderHost::RequestTextures(
406 uint32 requested_num_of_buffers,
407 const gfx::Size& dimensions,
408 uint32 texture_target,
409 const std::vector<gpu::Mailbox>& mailboxes) {
410 host()->SendUnsolicitedReply(
411 pp_resource(),
412 PpapiPluginMsg_VideoDecoder_RequestTextures(
413 requested_num_of_buffers,
414 PP_MakeSize(dimensions.width(), dimensions.height()),
415 texture_target,
416 mailboxes));
373 } 417 }
374 418
375 } // namespace content 419 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698