summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/video_decoder_resource.h
blob: aaa1b9571d4fae0d89609b193ad52e858bf912c2 (plain)
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
179
180
181
182
183
184
185
186
187
188
// 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 <queue>

#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.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 {
struct Mailbox;
namespace gles2 {
class GLES2Implementation;
}
}

namespace ppapi {

class PPB_Graphics3D_Shared;
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 Initialize(PP_Resource graphics_context,
                     PP_VideoProfile profile,
                     PP_HardwareAcceleration acceleration,
                     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(scoped_ptr<base::SharedMemory> shm,
              uint32_t size,
              uint32_t shm_id);
    ~ShmBuffer();

    const scoped_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,
                                  const std::vector<gpu::Mailbox>& mailboxes);
  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();

  // ScopedVector to own the shared memory buffers.
  ScopedVector<ShmBuffer> shm_buffers_;

  // List of available shared memory buffers.
  typedef std::vector<ShmBuffer*> ShmBufferList;
  ShmBufferList available_shm_buffers_;

  // Map of GL texture id to texture info.
  typedef base::hash_map<uint32_t, Texture> TextureMap;
  TextureMap textures_;

  // Queue of received pictures.
  typedef std::queue<Picture> PictureQueue;
  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];

  // 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_