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

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: Fix include order. 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.
181 delete shm_buffers_[shm_id]; 186 delete shm_buffers_[shm_id];
182 shm_buffers_[shm_id] = shm.release(); 187 shm_buffers_[shm_id] = shm.release();
183 } 188 }
184 189
185 #if defined(OS_WIN) 190 #if defined(OS_WIN)
186 base::PlatformFile platform_file = shm_handle; 191 base::PlatformFile platform_file = shm_handle;
187 #elif defined(OS_POSIX) 192 #elif defined(OS_POSIX)
188 base::PlatformFile platform_file = shm_handle.fd; 193 base::PlatformFile platform_file = shm_handle.fd;
189 #else 194 #else
190 #error Not implemented. 195 #error Not implemented.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture( 260 int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture(
256 ppapi::host::HostMessageContext* context, 261 ppapi::host::HostMessageContext* context,
257 uint32_t texture_id) { 262 uint32_t texture_id) {
258 if (!initialized_) 263 if (!initialized_)
259 return PP_ERROR_FAILED; 264 return PP_ERROR_FAILED;
260 DCHECK(decoder_); 265 DCHECK(decoder_);
261 if (reset_reply_context_.is_valid()) 266 if (reset_reply_context_.is_valid())
262 return PP_ERROR_FAILED; 267 return PP_ERROR_FAILED;
263 268
264 decoder_->ReusePictureBuffer(texture_id); 269 decoder_->ReusePictureBuffer(texture_id);
265
266 return PP_OK; 270 return PP_OK;
267 } 271 }
268 272
269 int32_t PepperVideoDecoderHost::OnHostMsgFlush( 273 int32_t PepperVideoDecoderHost::OnHostMsgFlush(
270 ppapi::host::HostMessageContext* context) { 274 ppapi::host::HostMessageContext* context) {
271 if (!initialized_) 275 if (!initialized_)
272 return PP_ERROR_FAILED; 276 return PP_ERROR_FAILED;
273 DCHECK(decoder_); 277 DCHECK(decoder_);
274 if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) 278 if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid())
275 return PP_ERROR_FAILED; 279 return PP_ERROR_FAILED;
(...skipping 15 matching lines...) Expand all
291 reset_reply_context_ = context->MakeReplyMessageContext(); 295 reset_reply_context_ = context->MakeReplyMessageContext();
292 decoder_->Reset(); 296 decoder_->Reset();
293 297
294 return PP_OK_COMPLETIONPENDING; 298 return PP_OK_COMPLETIONPENDING;
295 } 299 }
296 300
297 void PepperVideoDecoderHost::ProvidePictureBuffers( 301 void PepperVideoDecoderHost::ProvidePictureBuffers(
298 uint32 requested_num_of_buffers, 302 uint32 requested_num_of_buffers,
299 const gfx::Size& dimensions, 303 const gfx::Size& dimensions,
300 uint32 texture_target) { 304 uint32 texture_target) {
301 DCHECK(RenderThreadImpl::current()); 305 RequestTextures(requested_num_of_buffers,
302 host()->SendUnsolicitedReply( 306 dimensions,
303 pp_resource(), 307 texture_target,
304 PpapiPluginMsg_VideoDecoder_RequestTextures( 308 std::vector<gpu::Mailbox>());
305 requested_num_of_buffers,
306 PP_MakeSize(dimensions.width(), dimensions.height()),
307 texture_target));
308 } 309 }
309 310
310 void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { 311 void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) {
311 DCHECK(RenderThreadImpl::current());
312 host()->SendUnsolicitedReply( 312 host()->SendUnsolicitedReply(
313 pp_resource(), 313 pp_resource(),
314 PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(), 314 PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(),
315 picture.picture_buffer_id())); 315 picture.picture_buffer_id()));
316 } 316 }
317 317
318 void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) { 318 void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) {
319 DCHECK(RenderThreadImpl::current());
320 host()->SendUnsolicitedReply( 319 host()->SendUnsolicitedReply(
321 pp_resource(), 320 pp_resource(),
322 PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id)); 321 PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id));
323 } 322 }
324 323
324 void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer(
325 int32 bitstream_buffer_id) {
326 PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id);
327 if (it == pending_decodes_.end()) {
328 NOTREACHED();
329 return;
330 }
331 const PendingDecode& pending_decode = it->second;
332 host()->SendReply(
333 pending_decode.reply_context,
334 PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id));
335 shm_buffer_busy_[pending_decode.shm_id] = false;
336 pending_decodes_.erase(it);
337 }
338
339 void PepperVideoDecoderHost::NotifyFlushDone() {
340 host()->SendReply(flush_reply_context_,
341 PpapiPluginMsg_VideoDecoder_FlushReply());
342 flush_reply_context_ = ppapi::host::ReplyMessageContext();
343 }
344
345 void PepperVideoDecoderHost::NotifyResetDone() {
346 host()->SendReply(reset_reply_context_,
347 PpapiPluginMsg_VideoDecoder_ResetReply());
348 reset_reply_context_ = ppapi::host::ReplyMessageContext();
349 }
350
325 void PepperVideoDecoderHost::NotifyError( 351 void PepperVideoDecoderHost::NotifyError(
326 media::VideoDecodeAccelerator::Error error) { 352 media::VideoDecodeAccelerator::Error error) {
327 DCHECK(RenderThreadImpl::current());
328 int32_t pp_error = PP_ERROR_FAILED; 353 int32_t pp_error = PP_ERROR_FAILED;
329 switch (error) { 354 switch (error) {
330 case media::VideoDecodeAccelerator::UNREADABLE_INPUT: 355 case media::VideoDecodeAccelerator::UNREADABLE_INPUT:
331 pp_error = PP_ERROR_MALFORMED_INPUT; 356 pp_error = PP_ERROR_MALFORMED_INPUT;
332 break; 357 break;
333 case media::VideoDecodeAccelerator::ILLEGAL_STATE: 358 case media::VideoDecodeAccelerator::ILLEGAL_STATE:
334 case media::VideoDecodeAccelerator::INVALID_ARGUMENT: 359 case media::VideoDecodeAccelerator::INVALID_ARGUMENT:
335 case media::VideoDecodeAccelerator::PLATFORM_FAILURE: 360 case media::VideoDecodeAccelerator::PLATFORM_FAILURE:
336 case media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM: 361 case media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM:
337 pp_error = PP_ERROR_RESOURCE_FAILED; 362 pp_error = PP_ERROR_RESOURCE_FAILED;
338 break; 363 break;
339 // No default case, to catch unhandled enum values. 364 // No default case, to catch unhandled enum values.
340 } 365 }
341 host()->SendUnsolicitedReply( 366 host()->SendUnsolicitedReply(
342 pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error)); 367 pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error));
343 } 368 }
344 369
345 void PepperVideoDecoderHost::NotifyResetDone() { 370 void PepperVideoDecoderHost::OnInitializeComplete(int32_t result) {
346 DCHECK(RenderThreadImpl::current()); 371 if (!initialized_) {
347 host()->SendReply(reset_reply_context_, 372 if (result == PP_OK)
348 PpapiPluginMsg_VideoDecoder_ResetReply()); 373 initialized_ = true;
349 reset_reply_context_ = ppapi::host::ReplyMessageContext(); 374 initialize_reply_context_.params.set_result(result);
375 host()->SendReply(initialize_reply_context_,
376 PpapiPluginMsg_VideoDecoder_InitializeReply());
377 }
350 } 378 }
351 379
352 void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( 380 const uint8_t* PepperVideoDecoderHost::DecodeIdToAddress(uint32_t decode_id) {
353 int32 bitstream_buffer_id) { 381 PendingDecodeMap::const_iterator it = pending_decodes_.find(decode_id);
354 DCHECK(RenderThreadImpl::current()); 382 DCHECK(it != pending_decodes_.end());
355 PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id); 383 uint32_t shm_id = it->second.shm_id;
356 if (it == pending_decodes_.end()) { 384 return static_cast<uint8_t*>(shm_buffers_[shm_id]->memory());
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 } 385 }
367 386
368 void PepperVideoDecoderHost::NotifyFlushDone() { 387 void PepperVideoDecoderHost::RequestTextures(
369 DCHECK(RenderThreadImpl::current()); 388 uint32 requested_num_of_buffers,
370 host()->SendReply(flush_reply_context_, 389 const gfx::Size& dimensions,
371 PpapiPluginMsg_VideoDecoder_FlushReply()); 390 uint32 texture_target,
372 flush_reply_context_ = ppapi::host::ReplyMessageContext(); 391 const std::vector<gpu::Mailbox>& mailboxes) {
392 host()->SendUnsolicitedReply(
393 pp_resource(),
394 PpapiPluginMsg_VideoDecoder_RequestTextures(
395 requested_num_of_buffers,
396 PP_MakeSize(dimensions.width(), dimensions.height()),
397 texture_target,
398 mailboxes));
373 } 399 }
374 400
375 } // namespace content 401 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/pepper/pepper_video_decoder_host.h ('k') | content/renderer/pepper/video_decoder_shim.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698