1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
// Copyright 2014 The Chromium Authors
// 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 <unordered_map>
#include <vector>
#include "base/containers/queue.h"
#include "base/memory/scoped_refptr.h"
#include "gpu/command_buffer/common/mailbox.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(const VideoDecoderResource&) = delete;
VideoDecoderResource& operator=(const VideoDecoderResource&) = delete;
~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(base::UnsafeSharedMemoryRegion region, uint32_t shm_id);
~ShmBuffer();
base::UnsafeSharedMemoryRegion region;
base::WritableSharedMemoryMapping mapping;
void* addr = nullptr;
// 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 a shared image received from the decoder.
struct ReceivedSharedImage {
int32_t decode_id;
gpu::Mailbox mailbox;
PP_Size size;
PP_Rect visible_rect;
};
// Unsolicited reply message handlers.
void OnPluginMsgSharedImageReady(const ResourceMessageReplyParams& params,
int32_t decode_id,
const gpu::Mailbox& mailbox,
const PP_Size& size,
const PP_Rect& visible_rect);
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 WriteNextSharedImage();
// 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_;
// Queue of received shared images.
base::queue<ReceivedSharedImage> received_shared_images_;
// 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_;
// |used_shared_images_| maps texture names to ReceivedSharedImages that are
// in use by the plugin.
base::flat_map<uint32_t, ReceivedSharedImage> used_shared_images_;
};
} // namespace proxy
} // namespace ppapi
#endif // PPAPI_PROXY_VIDEO_DECODER_RESOURCE_H_
|