146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/video_decoder_resource.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_cmd_helper.h" 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h" 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ipc/ipc_message.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/c/ppb_opengles2.h" 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/plugin_dispatcher.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/ppb_graphics_3d_proxy.h" 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/serialized_handle.h" 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/video_decoder_constants.h" 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/shared_impl/ppb_graphics_3d_shared.h" 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h" 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/thunk/enter.h" 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using ppapi::thunk::EnterResourceNoLock; 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using ppapi::thunk::PPB_Graphics3D_API; 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using ppapi::thunk::PPB_VideoDecoder_API; 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace ppapi { 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace proxy { 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::ShmBuffer::ShmBuffer( 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<base::SharedMemory> shm_ptr, 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t size, 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t shm_id) 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : shm(shm_ptr.Pass()), addr(NULL), shm_id(shm_id) { 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (shm->Map(size)) 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) addr = shm->memory(); 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::ShmBuffer::~ShmBuffer() { 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::Texture::Texture(uint32_t texture_target, 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const PP_Size& size) 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : texture_target(texture_target), size(size) { 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::Texture::~Texture() { 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::Picture::Picture(int32_t decode_id, uint32_t texture_id) 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : decode_id(decode_id), texture_id(texture_id) { 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::Picture::~Picture() { 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::VideoDecoderResource(Connection connection, 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PP_Instance instance) 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : PluginResource(connection, instance), 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) num_decodes_(0), 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) get_picture_(NULL), 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_(NULL), 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) initialized_(false), 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) testing_(false), 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Set |decoder_last_error_| to PP_OK after successful initialization. 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // This makes error checking a little more concise, since we can check 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // that the decoder has been initialized and hasn't returned an error by 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // just testing |decoder_last_error_|. 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decoder_last_error_(PP_ERROR_FAILED) { 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Clear the decode_ids_ array. 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) memset(decode_ids_, 0, arraysize(decode_ids_)); 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SendCreate(RENDERER, PpapiHostMsg_VideoDecoder_Create()); 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)VideoDecoderResource::~VideoDecoderResource() { 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Destroy any textures which haven't been dismissed. 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) TextureMap::iterator it = textures_.begin(); 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (; it != textures_.end(); ++it) 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeleteGLTexture(it->first); 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)PPB_VideoDecoder_API* VideoDecoderResource::AsPPB_VideoDecoder_API() { 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return this; 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint32_t VideoDecoderResource::Initialize0_1( 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PP_Resource graphics_context, 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PP_VideoProfile profile, 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PP_Bool allow_software_fallback, 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return Initialize(graphics_context, 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile, 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci allow_software_fallback 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? PP_HARDWAREACCELERATION_WITHFALLBACK 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : PP_HARDWAREACCELERATION_ONLY, 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint32_t VideoDecoderResource::Initialize( 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PP_Resource graphics_context, 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PP_VideoProfile profile, 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PP_HardwareAcceleration acceleration, 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<TrackedCallback> callback) { 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (initialized_) 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (profile < 0 || profile > PP_VIDEOPROFILE_MAX) 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_BADARGUMENT; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (initialize_callback_.get()) 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_INPROGRESS; 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!graphics_context) 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_BADRESOURCE; 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) HostResource host_resource; 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!testing_) { 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Create a new Graphics3D resource that can create texture resources to 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // share with the plugin. We can't use the plugin's Graphics3D, since we 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // create textures on a proxy thread, and would interfere with the plugin. 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) thunk::EnterResourceCreationNoLock enter_create(pp_instance()); 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (enter_create.failed()) 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int32_t attrib_list[] = {PP_GRAPHICS3DATTRIB_NONE}; 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) graphics3d_ = 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ScopedPPResource(ScopedPPResource::PassRef(), 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) enter_create.functions()->CreateGraphics3D( 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pp_instance(), graphics_context, attrib_list)); 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EnterResourceNoLock<PPB_Graphics3D_API> enter_graphics(graphics3d_.get(), 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) false); 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (enter_graphics.failed()) 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_BADRESOURCE; 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPB_Graphics3D_Shared* ppb_graphics3d_shared = 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static_cast<PPB_Graphics3D_Shared*>(enter_graphics.object()); 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_ = ppb_graphics3d_shared->gles2_impl(); 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) host_resource = ppb_graphics3d_shared->host_resource(); 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) initialize_callback_ = callback; 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Call<PpapiPluginMsg_VideoDecoder_InitializeReply>( 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RENDERER, 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiHostMsg_VideoDecoder_Initialize( 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci host_resource, profile, acceleration), 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&VideoDecoderResource::OnPluginMsgInitializeComplete, this)); 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t VideoDecoderResource::Decode(uint32_t decode_id, 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t size, 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const void* buffer, 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (decoder_last_error_) 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return decoder_last_error_; 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (flush_callback_.get() || reset_callback_.get()) 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (decode_callback_.get()) 15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_INPROGRESS; 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (size > kMaximumBitstreamBufferSize) 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_NOMEMORY; 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If we allow the plugin to call Decode again, we must have somewhere to 16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // copy their buffer. 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!available_shm_buffers_.empty() || 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shm_buffers_.size() < kMaximumPendingDecodes); 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Count up, wrapping back to 0 before overflowing. 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int32_t uid = ++num_decodes_; 17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (uid == std::numeric_limits<int32_t>::max()) 17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) num_decodes_ = 0; 17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Save decode_id in a ring buffer. The ring buffer is sized to store 17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // decode_id for the maximum picture delay. 17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decode_ids_[uid % kMaximumPictureDelay] = decode_id; 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (available_shm_buffers_.empty() || 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) available_shm_buffers_.back()->shm->mapped_size() < size) { 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t shm_id; 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (shm_buffers_.size() < kMaximumPendingDecodes) { 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Signal the host to create a new shm buffer by passing an index outside 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the legal range. 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shm_id = static_cast<uint32_t>(shm_buffers_.size()); 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Signal the host to grow a buffer by passing a legal index. Choose the 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // last available shm buffer for simplicity. 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shm_id = available_shm_buffers_.back()->shm_id; 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) available_shm_buffers_.pop_back(); 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Synchronously get shared memory. Use GenericSyncCall so we can get the 19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // reply params, which contain the handle. 19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t shm_size = 0; 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::Message reply; 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ResourceMessageReplyParams reply_params; 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int32_t result = 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GenericSyncCall(RENDERER, 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiHostMsg_VideoDecoder_GetShm(shm_id, size), 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &reply, 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &reply_params); 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (result != PP_OK) 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!UnpackMessage<PpapiPluginMsg_VideoDecoder_GetShmReply>(reply, 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &shm_size)) 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::SharedMemoryHandle shm_handle = base::SharedMemory::NULLHandle(); 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!reply_params.TakeSharedMemoryHandleAtIndex(0, &shm_handle)) 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_NOMEMORY; 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<base::SharedMemory> shm( 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new base::SharedMemory(shm_handle, false /* read_only */)); 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ShmBuffer> shm_buffer( 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new ShmBuffer(shm.Pass(), shm_size, shm_id)); 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!shm_buffer->addr) 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_NOMEMORY; 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) available_shm_buffers_.push_back(shm_buffer.get()); 21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (shm_buffers_.size() < kMaximumPendingDecodes) { 21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shm_buffers_.push_back(shm_buffer.release()); 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Delete manually since ScopedVector won't delete the existing element if 22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // we just assign it. 22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) delete shm_buffers_[shm_id]; 22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shm_buffers_[shm_id] = shm_buffer.release(); 22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // At this point we should have shared memory to hold the plugin's buffer. 22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!available_shm_buffers_.empty() && 22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) available_shm_buffers_.back()->shm->mapped_size() >= size); 23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ShmBuffer* shm_buffer = available_shm_buffers_.back(); 23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) available_shm_buffers_.pop_back(); 23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) memcpy(shm_buffer->addr, buffer, size); 23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Call<PpapiPluginMsg_VideoDecoder_DecodeReply>( 23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RENDERER, 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiHostMsg_VideoDecoder_Decode(shm_buffer->shm_id, size, uid), 23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&VideoDecoderResource::OnPluginMsgDecodeComplete, this)); 23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If we have another free buffer, or we can still create new buffers, let 24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the plugin call Decode again. 24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!available_shm_buffers_.empty() || 24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shm_buffers_.size() < kMaximumPendingDecodes) 24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK; 24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // All buffers are busy and we can't create more. Delay completion until a 24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // buffer is available. 24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decode_callback_ = callback; 24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t VideoDecoderResource::GetPicture( 25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PP_VideoPicture* picture, 25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (decoder_last_error_) 25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return decoder_last_error_; 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (reset_callback_.get()) 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (get_picture_callback_.get()) 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_INPROGRESS; 26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the next picture is ready, return it synchronously. 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!received_pictures_.empty()) { 26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WriteNextPicture(picture); 26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK; 26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) get_picture_callback_ = callback; 26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) get_picture_ = picture; 27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::RecyclePicture(const PP_VideoPicture* picture) { 27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (decoder_last_error_) 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Post(RENDERER, PpapiHostMsg_VideoDecoder_RecyclePicture(picture->texture_id)); 27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t VideoDecoderResource::Flush(scoped_refptr<TrackedCallback> callback) { 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (decoder_last_error_) 28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return decoder_last_error_; 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (reset_callback_.get()) 28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (flush_callback_.get()) 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_INPROGRESS; 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) flush_callback_ = callback; 28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Call<PpapiPluginMsg_VideoDecoder_FlushReply>( 29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RENDERER, 29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiHostMsg_VideoDecoder_Flush(), 29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&VideoDecoderResource::OnPluginMsgFlushComplete, this)); 29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t VideoDecoderResource::Reset(scoped_refptr<TrackedCallback> callback) { 29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (decoder_last_error_) 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return decoder_last_error_; 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (flush_callback_.get()) 30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_FAILED; 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (reset_callback_.get()) 30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_ERROR_INPROGRESS; 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) reset_callback_ = callback; 30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Cause any pending Decode or GetPicture callbacks to abort after we return, 30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // to avoid reentering the plugin. 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (TrackedCallback::IsPending(decode_callback_)) 30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decode_callback_->PostAbort(); 31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decode_callback_ = NULL; 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (TrackedCallback::IsPending(get_picture_callback_)) 31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) get_picture_callback_->PostAbort(); 31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) get_picture_callback_ = NULL; 31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Call<PpapiPluginMsg_VideoDecoder_ResetReply>( 31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RENDERER, 31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiHostMsg_VideoDecoder_Reset(), 31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&VideoDecoderResource::OnPluginMsgResetComplete, this)); 31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnReplyReceived( 32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params, 32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const IPC::Message& msg) { 32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_BEGIN_MESSAGE_MAP(VideoDecoderResource, msg) 32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( 32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiPluginMsg_VideoDecoder_RequestTextures, OnPluginMsgRequestTextures) 32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( 32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiPluginMsg_VideoDecoder_PictureReady, OnPluginMsgPictureReady) 33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( 33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiPluginMsg_VideoDecoder_DismissPicture, OnPluginMsgDismissPicture) 33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PpapiPluginMsg_VideoDecoder_NotifyError, OnPluginMsgNotifyError) 33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED( 33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PluginResource::OnReplyReceived(params, msg)) 33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PPAPI_END_MESSAGE_MAP() 33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::SetForTest() { 34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) testing_ = true; 34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgRequestTextures( 34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params, 34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t num_textures, 34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const PP_Size& size, 347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint32_t texture_target, 348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::vector<gpu::Mailbox>& mailboxes) { 34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(num_textures); 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(mailboxes.empty() || mailboxes.size() == num_textures); 35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<uint32_t> texture_ids(num_textures); 35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (gles2_impl_) { 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->GenTextures(num_textures, &texture_ids.front()); 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (uint32_t i = 0; i < num_textures; ++i) { 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->ActiveTexture(GL_TEXTURE0); 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->BindTexture(texture_target, texture_ids[i]); 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->TexParameteri( 35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->TexParameteri( 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->TexParameterf( 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->TexParameterf( 36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (texture_target == GL_TEXTURE_2D) { 36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->TexImage2D(texture_target, 36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 0, 36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GL_RGBA, 37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size.width, 37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size.height, 37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 0, 37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GL_RGBA, 37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GL_UNSIGNED_BYTE, 37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NULL); 37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!mailboxes.empty()) { 378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gles2_impl_->ProduceTextureCHROMIUM( 379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GL_TEXTURE_2D, reinterpret_cast<const GLbyte*>(mailboxes[i].name)); 380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) textures_.insert( 38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::make_pair(texture_ids[i], Texture(texture_target, size))); 38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->Flush(); 38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(testing_); 38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Create some fake texture ids so we can test picture handling. 38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (uint32_t i = 0; i < num_textures; ++i) { 39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) texture_ids[i] = i + 1; 39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) textures_.insert( 39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::make_pair(texture_ids[i], Texture(texture_target, size))); 39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Post(RENDERER, PpapiHostMsg_VideoDecoder_AssignTextures(size, texture_ids)); 39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgPictureReady( 40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params, 40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int32_t decode_id, 40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t texture_id) { 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) received_pictures_.push(Picture(decode_id, texture_id)); 40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (TrackedCallback::IsPending(get_picture_callback_)) { 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The plugin may call GetPicture in its callback. 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback; 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.swap(get_picture_callback_); 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PP_VideoPicture* picture = get_picture_; 41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) get_picture_ = NULL; 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) WriteNextPicture(picture); 41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->Run(PP_OK); 41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgDismissPicture( 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params, 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t texture_id) { 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeleteGLTexture(texture_id); 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) textures_.erase(texture_id); 42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 42346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgNotifyError( 42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params, 42546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int32_t error) { 42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decoder_last_error_ = error; 42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Cause any pending callbacks to run immediately. Reentrancy isn't a problem, 42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // since the plugin wasn't calling us. 42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RunCallbackWithError(&initialize_callback_); 43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RunCallbackWithError(&decode_callback_); 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RunCallbackWithError(&get_picture_callback_); 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RunCallbackWithError(&flush_callback_); 43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RunCallbackWithError(&reset_callback_); 43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgInitializeComplete( 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params) { 43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) decoder_last_error_ = params.result(); 43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (decoder_last_error_ == PP_OK) 44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) initialized_ = true; 44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Let the plugin call Initialize again from its callback in case of failure. 44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback; 44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.swap(initialize_callback_); 44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->Run(decoder_last_error_); 44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgDecodeComplete( 44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params, 45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t shm_id) { 45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (shm_id >= shm_buffers_.size()) { 45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED(); 45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Make the shm buffer available. 45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) available_shm_buffers_.push_back(shm_buffers_[shm_id]); 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the plugin is waiting, let it call Decode again. 4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (decode_callback_.get()) { 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback; 46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.swap(decode_callback_); 46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->Run(PP_OK); 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgFlushComplete( 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params) { 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // All shm buffers should have been made available by now. 46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(shm_buffers_.size(), available_shm_buffers_.size()); 46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (get_picture_callback_.get()) { 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback; 47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.swap(get_picture_callback_); 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->Abort(); 47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback; 47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.swap(flush_callback_); 47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->Run(params.result()); 47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::OnPluginMsgResetComplete( 48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ResourceMessageReplyParams& params) { 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // All shm buffers should have been made available by now. 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(shm_buffers_.size(), available_shm_buffers_.size()); 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Recycle any pictures which haven't been passed to the plugin. 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (!received_pictures_.empty()) { 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Post(RENDERER, PpapiHostMsg_VideoDecoder_RecyclePicture( 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch received_pictures_.front().texture_id)); 489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) received_pictures_.pop(); 490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> callback; 49346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.swap(reset_callback_); 49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->Run(params.result()); 49546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::RunCallbackWithError( 49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback>* callback) { 49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (TrackedCallback::IsPending(*callback)) { 50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<TrackedCallback> temp; 50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback->swap(temp); 50246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) temp->Run(decoder_last_error_); 50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 50446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 50546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 50646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::DeleteGLTexture(uint32_t id) { 50746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (gles2_impl_) { 50846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->DeleteTextures(1, &id); 50946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) gles2_impl_->Flush(); 51046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 51146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 51246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 51346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void VideoDecoderResource::WriteNextPicture(PP_VideoPicture* pp_picture) { 51446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!received_pictures_.empty()); 51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Picture& picture = received_pictures_.front(); 51646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Internally, we identify decodes by a unique id, which the host returns 51746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // to us in the picture. Use this to get the plugin's decode_id. 51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pp_picture->decode_id = decode_ids_[picture.decode_id % kMaximumPictureDelay]; 51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pp_picture->texture_id = picture.texture_id; 52046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) TextureMap::iterator it = textures_.find(picture.texture_id); 52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (it != textures_.end()) { 52246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pp_picture->texture_target = it->second.texture_target; 52346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pp_picture->texture_size = it->second.size; 52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED(); 52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) received_pictures_.pop(); 52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 52946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 53046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace proxy 53146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace ppapi 532