| // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef PPAPI_PROXY_VIDEO_DECODER_RESOURCE_H_ | |
| #define PPAPI_PROXY_VIDEO_DECODER_RESOURCE_H_ | |
| #include <stdint.h> | |
| #include <memory> | |
| #include <vector> | |
| #include "base/containers/hash_tables.h" | |
| #include "base/containers/queue.h" | |
| #include "base/macros.h" | |
| #include "base/memory/ref_counted.h" | |
| #include "ppapi/proxy/connection.h" | |
| #include "ppapi/proxy/plugin_resource.h" | |
| #include "ppapi/proxy/ppapi_proxy_export.h" | |
| #include "ppapi/shared_impl/resource.h" | |
| #include "ppapi/shared_impl/scoped_pp_resource.h" | |
| #include "ppapi/thunk/ppb_video_decoder_api.h" | |
| namespace gpu { | |
| namespace gles2 { | |
| class GLES2Implementation; | |
| } | |
| } | |
| namespace ppapi { | |
| class TrackedCallback; | |
| namespace proxy { | |
| class PPAPI_PROXY_EXPORT VideoDecoderResource | |
| : public PluginResource, | |
| public thunk::PPB_VideoDecoder_API { | |
| public: | |
| VideoDecoderResource(Connection connection, PP_Instance instance); | |
| ~VideoDecoderResource() override; | |
| // Resource overrides. | |
| thunk::PPB_VideoDecoder_API* AsPPB_VideoDecoder_API() override; | |
| // PPB_VideoDecoder_API implementation. | |
| int32_t Initialize0_1( | |
| PP_Resource graphics_context, | |
| PP_VideoProfile profile, | |
| PP_Bool allow_software_fallback, | |
| scoped_refptr<TrackedCallback> callback) override; | |
| int32_t Initialize0_2( | |
| PP_Resource graphics_context, | |
| PP_VideoProfile profile, | |
| PP_HardwareAcceleration acceleration, | |
| scoped_refptr<TrackedCallback> callback) override; | |
| int32_t Initialize(PP_Resource graphics_context, | |
| PP_VideoProfile profile, | |
| PP_HardwareAcceleration acceleration, | |
| uint32_t min_picture_count, | |
| scoped_refptr<TrackedCallback> callback) override; | |
| int32_t Decode(uint32_t decode_id, | |
| uint32_t size, | |
| const void* buffer, | |
| scoped_refptr<TrackedCallback> callback) override; | |
| int32_t GetPicture0_1( | |
| PP_VideoPicture_0_1* picture, | |
| scoped_refptr<TrackedCallback> callback) override; | |
| int32_t GetPicture(PP_VideoPicture* picture, | |
| scoped_refptr<TrackedCallback> callback) override; | |
| void RecyclePicture(const PP_VideoPicture* picture) override; | |
| int32_t Flush(scoped_refptr<TrackedCallback> callback) override; | |
| int32_t Reset(scoped_refptr<TrackedCallback> callback) override; | |
| // PluginResource implementation. | |
| void OnReplyReceived(const ResourceMessageReplyParams& params, | |
| const IPC::Message& msg) override; | |
| // Called only by unit tests. This bypasses Graphics3D setup, which doesn't | |
| // work in ppapi::proxy::PluginProxyTest. | |
| void SetForTest(); | |
| private: | |
| // Struct to hold a shared memory buffer. | |
| struct ShmBuffer { | |
| ShmBuffer(std::unique_ptr<base::SharedMemory> shm, | |
| uint32_t size, | |
| uint32_t shm_id); | |
| ~ShmBuffer(); | |
| const std::unique_ptr<base::SharedMemory> shm; | |
| void* addr; | |
| // Index into shm_buffers_ vector, used as an id. This should map 1:1 to | |
| // the index on the host side of the proxy. | |
| const uint32_t shm_id; | |
| }; | |
| // Struct to hold texture information. | |
| struct Texture { | |
| Texture(uint32_t texture_target, const PP_Size& size); | |
| ~Texture(); | |
| const uint32_t texture_target; | |
| const PP_Size size; | |
| }; | |
| // Struct to hold a picture received from the decoder. | |
| struct Picture { | |
| Picture(int32_t decode_id, | |
| uint32_t texture_id, | |
| const PP_Rect& visible_rect); | |
| ~Picture(); | |
| int32_t decode_id; | |
| uint32_t texture_id; | |
| PP_Rect visible_rect; | |
| }; | |
| // Unsolicited reply message handlers. | |
| void OnPluginMsgRequestTextures(const ResourceMessageReplyParams& params, | |
| uint32_t num_textures, | |
| const PP_Size& size, | |
| uint32_t texture_target); | |
| void OnPluginMsgPictureReady(const ResourceMessageReplyParams& params, | |
| int32_t decode_id, | |
| uint32_t texture_id, | |
| const PP_Rect& visible_rect); | |
| void OnPluginMsgDismissPicture(const ResourceMessageReplyParams& params, | |
| uint32_t texture_id); | |
| void OnPluginMsgNotifyError(const ResourceMessageReplyParams& params, | |
| int32_t error); | |
| // Reply message handlers for operations that are done in the host. | |
| void OnPluginMsgInitializeComplete(const ResourceMessageReplyParams& params); | |
| void OnPluginMsgDecodeComplete(const ResourceMessageReplyParams& params, | |
| uint32_t shm_id); | |
| void OnPluginMsgFlushComplete(const ResourceMessageReplyParams& params); | |
| void OnPluginMsgResetComplete(const ResourceMessageReplyParams& params); | |
| void RunCallbackWithError(scoped_refptr<TrackedCallback>* callback); | |
| void DeleteGLTexture(uint32_t texture_id); | |
| void WriteNextPicture(); | |
| // The shared memory buffers. | |
| std::vector<std::unique_ptr<ShmBuffer>> shm_buffers_; | |
| // List of available shared memory buffers. | |
| using ShmBufferList = std::vector<ShmBuffer*>; | |
| ShmBufferList available_shm_buffers_; | |
| // Map of GL texture id to texture info. | |
| using TextureMap = base::hash_map<uint32_t, Texture>; | |
| TextureMap textures_; | |
| // Queue of received pictures. | |
| using PictureQueue = base::queue<Picture>; | |
| PictureQueue received_pictures_; | |
| // Pending callbacks. | |
| scoped_refptr<TrackedCallback> initialize_callback_; | |
| scoped_refptr<TrackedCallback> decode_callback_; | |
| scoped_refptr<TrackedCallback> get_picture_callback_; | |
| scoped_refptr<TrackedCallback> flush_callback_; | |
| scoped_refptr<TrackedCallback> reset_callback_; | |
| // Number of Decode calls made, mod 2^31, to serve as a uid for each decode. | |
| int32_t num_decodes_; | |
| // The maximum delay (in Decode calls) before we receive a picture. If we | |
| // haven't received a picture from a Decode call after this many successive | |
| // calls to Decode, then we will never receive a picture from the call. | |
| // Note that this isn't guaranteed by H264 or other codecs. In practice, this | |
| // number is less than 16. Make it much larger just to be safe. | |
| // NOTE: because we count decodes mod 2^31, this value must be a power of 2. | |
| static const int kMaximumPictureDelay = 128; | |
| uint32_t decode_ids_[kMaximumPictureDelay]; | |
| uint32_t min_picture_count_; | |
| // State for pending get_picture_callback_. | |
| PP_VideoPicture* get_picture_; | |
| PP_VideoPicture_0_1* get_picture_0_1_; | |
| ScopedPPResource graphics3d_; | |
| gpu::gles2::GLES2Implementation* gles2_impl_; | |
| bool initialized_; | |
| bool testing_; | |
| int32_t decoder_last_error_; | |
| DISALLOW_COPY_AND_ASSIGN(VideoDecoderResource); | |
| }; | |
| } // namespace proxy | |
| } // namespace ppapi | |
| #endif // PPAPI_PROXY_VIDEO_DECODER_RESOURCE_H_ |