Index: content/renderer/pepper/pepper_video_decoder_host.cc |
diff --git a/content/renderer/pepper/pepper_video_decoder_host.cc b/content/renderer/pepper/pepper_video_decoder_host.cc |
index 16019f720b29e4e6be4a8e1d236043dfecd3802e..5a52c404bc3975e067dcacdd3c3843beec05547c 100644 |
--- a/content/renderer/pepper/pepper_video_decoder_host.cc |
+++ b/content/renderer/pepper/pepper_video_decoder_host.cc |
@@ -2,6 +2,10 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <GLES2/gl2.h> |
+#include <GLES2/gl2ext.h> |
+#include <GLES2/gl2extchromium.h> |
bbudge
2014/06/04 14:31:41
unnecessary.
|
+ |
#include "content/renderer/pepper/pepper_video_decoder_host.h" |
#include "base/bind.h" |
@@ -10,9 +14,7 @@ |
#include "content/public/renderer/render_thread.h" |
#include "content/public/renderer/renderer_ppapi_host.h" |
#include "content/renderer/pepper/ppb_graphics_3d_impl.h" |
-#include "content/renderer/render_thread_impl.h" |
-#include "content/renderer/render_view_impl.h" |
-#include "media/video/picture.h" |
+#include "media/filters/ffmpeg_video_decoder.h" |
#include "media/video/video_decode_accelerator.h" |
#include "ppapi/c/pp_completion_callback.h" |
#include "ppapi/c/pp_errors.h" |
@@ -119,9 +121,10 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( |
graphics_context.host_resource(), true); |
if (enter_graphics.failed()) |
return PP_ERROR_FAILED; |
- graphics3d_ = static_cast<PPB_Graphics3D_Impl*>(enter_graphics.object()); |
+ PPB_Graphics3D_Impl* graphics3d = |
+ static_cast<PPB_Graphics3D_Impl*>(enter_graphics.object()); |
- int command_buffer_route_id = graphics3d_->GetCommandBufferRouteId(); |
+ int command_buffer_route_id = graphics3d->GetCommandBufferRouteId(); |
if (!command_buffer_route_id) |
return PP_ERROR_FAILED; |
@@ -129,7 +132,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( |
// This is not synchronous, but subsequent IPC messages will be buffered, so |
// it is okay to immediately send IPC messages through the returned channel. |
- GpuChannelHost* channel = graphics3d_->channel(); |
+ GpuChannelHost* channel = graphics3d->channel(); |
DCHECK(channel); |
decoder_ = channel->CreateVideoDecoder(command_buffer_route_id); |
if (decoder_ && decoder_->Initialize(media_profile, this)) { |
@@ -138,8 +141,14 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( |
} |
decoder_.reset(); |
- // TODO(bbudge) Implement software fallback. |
- return PP_ERROR_NOTSUPPORTED; |
+ if (!allow_software_fallback) |
+ return PP_ERROR_NOTSUPPORTED; |
+ |
+ software_decoder_.reset(new VideoDecoderProxy(this)); |
+ initialize_reply_context_ = context->MakeReplyMessageContext(); |
+ software_decoder_->Initialize(media_profile); |
+ |
+ return PP_OK_COMPLETIONPENDING; |
} |
int32_t PepperVideoDecoderHost::OnHostMsgGetShm( |
@@ -208,7 +217,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgDecode( |
int32_t decode_id) { |
if (!initialized_) |
return PP_ERROR_FAILED; |
- DCHECK(decoder_); |
+ DCHECK(decoder_ || software_decoder_); |
// |shm_id| is just an index into shm_buffers_. Make sure it's in range. |
if (static_cast<size_t>(shm_id) >= shm_buffers_.size()) |
return PP_ERROR_FAILED; |
@@ -226,8 +235,13 @@ int32_t PepperVideoDecoderHost::OnHostMsgDecode( |
decode_id, PendingDecode(shm_id, context->MakeReplyMessageContext()))); |
shm_buffer_busy_[shm_id] = true; |
- decoder_->Decode( |
- media::BitstreamBuffer(decode_id, shm_buffers_[shm_id]->handle(), size)); |
+ base::SharedMemory* shm = shm_buffers_[shm_id]; |
+ if (decoder_) { |
+ decoder_->Decode(media::BitstreamBuffer(decode_id, shm->handle(), size)); |
+ } else { |
+ software_decoder_->Decode( |
+ decode_id, static_cast<uint8_t*>(shm->memory()), size); |
+ } |
return PP_OK_COMPLETIONPENDING; |
} |
@@ -238,17 +252,21 @@ int32_t PepperVideoDecoderHost::OnHostMsgAssignTextures( |
const std::vector<uint32_t>& texture_ids) { |
if (!initialized_) |
return PP_ERROR_FAILED; |
- DCHECK(decoder_); |
- |
- std::vector<media::PictureBuffer> picture_buffers; |
- for (uint32 i = 0; i < texture_ids.size(); i++) { |
- media::PictureBuffer buffer( |
- texture_ids[i], // Use the texture_id to identify the buffer. |
- gfx::Size(size.width, size.height), |
- texture_ids[i]); |
- picture_buffers.push_back(buffer); |
+ DCHECK(decoder_ || software_decoder_); |
+ |
+ if (decoder_) { |
+ std::vector<media::PictureBuffer> picture_buffers; |
+ for (uint32 i = 0; i < texture_ids.size(); i++) { |
+ media::PictureBuffer buffer( |
+ texture_ids[i], // Use the texture_id to identify the buffer. |
+ gfx::Size(size.width, size.height), |
+ texture_ids[i]); |
+ picture_buffers.push_back(buffer); |
+ } |
+ decoder_->AssignPictureBuffers(picture_buffers); |
+ } else { |
+ software_decoder_->AssignTextures(texture_ids); |
} |
- decoder_->AssignPictureBuffers(picture_buffers); |
return PP_OK; |
} |
@@ -257,11 +275,14 @@ int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture( |
uint32_t texture_id) { |
if (!initialized_) |
return PP_ERROR_FAILED; |
- DCHECK(decoder_); |
+ DCHECK(decoder_ || software_decoder_); |
if (reset_reply_context_.is_valid()) |
return PP_ERROR_FAILED; |
- |
- decoder_->ReusePictureBuffer(texture_id); |
+ if (decoder_) { |
+ decoder_->ReusePictureBuffer(texture_id); |
+ } else { |
+ software_decoder_->RecycleTexture(texture_id); |
+ } |
return PP_OK; |
} |
@@ -270,12 +291,15 @@ int32_t PepperVideoDecoderHost::OnHostMsgFlush( |
ppapi::host::HostMessageContext* context) { |
if (!initialized_) |
return PP_ERROR_FAILED; |
- DCHECK(decoder_); |
+ DCHECK(decoder_ || software_decoder_); |
if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) |
return PP_ERROR_FAILED; |
flush_reply_context_ = context->MakeReplyMessageContext(); |
- decoder_->Flush(); |
+ if (decoder_) |
+ decoder_->Flush(); |
+ else |
+ software_decoder_->Flush(); |
return PP_OK_COMPLETIONPENDING; |
} |
@@ -284,12 +308,15 @@ int32_t PepperVideoDecoderHost::OnHostMsgReset( |
ppapi::host::HostMessageContext* context) { |
if (!initialized_) |
return PP_ERROR_FAILED; |
- DCHECK(decoder_); |
+ DCHECK(decoder_ || software_decoder_); |
if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) |
return PP_ERROR_FAILED; |
reset_reply_context_ = context->MakeReplyMessageContext(); |
- decoder_->Reset(); |
+ if (decoder_) |
+ decoder_->Reset(); |
+ else |
+ software_decoder_->Reset(); |
return PP_OK_COMPLETIONPENDING; |
} |
@@ -298,17 +325,13 @@ void PepperVideoDecoderHost::ProvidePictureBuffers( |
uint32 requested_num_of_buffers, |
const gfx::Size& dimensions, |
uint32 texture_target) { |
- DCHECK(RenderThreadImpl::current()); |
- host()->SendUnsolicitedReply( |
- pp_resource(), |
- PpapiPluginMsg_VideoDecoder_RequestTextures( |
- requested_num_of_buffers, |
- PP_MakeSize(dimensions.width(), dimensions.height()), |
- texture_target)); |
+ RequestTextures(requested_num_of_buffers, |
+ dimensions, |
+ texture_target, |
+ std::vector<gpu::Mailbox>()); |
} |
void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { |
- DCHECK(RenderThreadImpl::current()); |
host()->SendUnsolicitedReply( |
pp_resource(), |
PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(), |
@@ -316,15 +339,40 @@ void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { |
} |
void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) { |
- DCHECK(RenderThreadImpl::current()); |
host()->SendUnsolicitedReply( |
pp_resource(), |
PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id)); |
} |
+void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( |
+ int32 bitstream_buffer_id) { |
+ PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id); |
+ if (it == pending_decodes_.end()) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ const PendingDecode& pending_decode = it->second; |
+ host()->SendReply( |
+ pending_decode.reply_context, |
+ PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id)); |
+ shm_buffer_busy_[pending_decode.shm_id] = false; |
+ pending_decodes_.erase(it); |
+} |
+ |
+void PepperVideoDecoderHost::NotifyFlushDone() { |
+ host()->SendReply(flush_reply_context_, |
+ PpapiPluginMsg_VideoDecoder_FlushReply()); |
+ flush_reply_context_ = ppapi::host::ReplyMessageContext(); |
+} |
+ |
+void PepperVideoDecoderHost::NotifyResetDone() { |
+ host()->SendReply(reset_reply_context_, |
+ PpapiPluginMsg_VideoDecoder_ResetReply()); |
+ reset_reply_context_ = ppapi::host::ReplyMessageContext(); |
+} |
+ |
void PepperVideoDecoderHost::NotifyError( |
media::VideoDecodeAccelerator::Error error) { |
- DCHECK(RenderThreadImpl::current()); |
int32_t pp_error = PP_ERROR_FAILED; |
switch (error) { |
case media::VideoDecodeAccelerator::UNREADABLE_INPUT: |
@@ -338,38 +386,35 @@ void PepperVideoDecoderHost::NotifyError( |
break; |
// No default case, to catch unhandled enum values. |
} |
- host()->SendUnsolicitedReply( |
- pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error)); |
+ NotifyError(pp_error); |
} |
-void PepperVideoDecoderHost::NotifyResetDone() { |
- DCHECK(RenderThreadImpl::current()); |
- host()->SendReply(reset_reply_context_, |
- PpapiPluginMsg_VideoDecoder_ResetReply()); |
- reset_reply_context_ = ppapi::host::ReplyMessageContext(); |
+void PepperVideoDecoderHost::OnInitializeComplete(int32_t result) { |
+ if (!initialized_) { |
+ initialized_ = true; |
+ initialize_reply_context_.params.set_result(result); |
+ host()->SendReply(initialize_reply_context_, |
+ PpapiPluginMsg_VideoDecoder_InitializeReply()); |
+ } |
} |
-void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( |
- int32 bitstream_buffer_id) { |
- DCHECK(RenderThreadImpl::current()); |
- PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id); |
- if (it == pending_decodes_.end()) { |
- NOTREACHED(); |
- return; |
- } |
- const PendingDecode& pending_decode = it->second; |
- host()->SendReply( |
- pending_decode.reply_context, |
- PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id)); |
- shm_buffer_busy_[pending_decode.shm_id] = false; |
- pending_decodes_.erase(it); |
+void PepperVideoDecoderHost::RequestTextures( |
+ uint32 requested_num_of_buffers, |
+ const gfx::Size& dimensions, |
+ uint32 texture_target, |
+ const std::vector<gpu::Mailbox>& mailboxes) { |
+ host()->SendUnsolicitedReply( |
+ pp_resource(), |
+ PpapiPluginMsg_VideoDecoder_RequestTextures( |
+ requested_num_of_buffers, |
+ PP_MakeSize(dimensions.width(), dimensions.height()), |
+ texture_target, |
+ mailboxes)); |
} |
-void PepperVideoDecoderHost::NotifyFlushDone() { |
- DCHECK(RenderThreadImpl::current()); |
- host()->SendReply(flush_reply_context_, |
- PpapiPluginMsg_VideoDecoder_FlushReply()); |
- flush_reply_context_ = ppapi::host::ReplyMessageContext(); |
+void PepperVideoDecoderHost::NotifyError(int32_t pp_error) { |
+ host()->SendUnsolicitedReply( |
+ pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error)); |
} |
} // namespace content |