Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1423)

Side by Side Diff: webkit/plugins/ppapi/ppb_video_decoder_impl.cc

Issue 7545014: Implement PPAPI VideoDecode out-of-process support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: responses to ddorwin and piman Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/ppapi/ppb_video_decoder_impl.h" 5 #include "webkit/plugins/ppapi/ppb_video_decoder_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 16 matching lines...) Expand all
27 using ppapi::thunk::EnterResourceNoLock; 27 using ppapi::thunk::EnterResourceNoLock;
28 using ppapi::thunk::PPB_Buffer_API; 28 using ppapi::thunk::PPB_Buffer_API;
29 using ppapi::thunk::PPB_Context3D_API; 29 using ppapi::thunk::PPB_Context3D_API;
30 using ppapi::thunk::PPB_VideoDecoder_API; 30 using ppapi::thunk::PPB_VideoDecoder_API;
31 31
32 namespace webkit { 32 namespace webkit {
33 namespace ppapi { 33 namespace ppapi {
34 34
35 PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance) 35 PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance)
36 : Resource(instance), 36 : Resource(instance),
37 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 37 VideoDecoderImpl(true) {
38 context3d_id_(0),
39 flush_callback_(PP_BlockUntilComplete()),
40 reset_callback_(PP_BlockUntilComplete()),
41 gles2_impl_(NULL) {
42 ppp_videodecoder_ = 38 ppp_videodecoder_ =
43 static_cast<const PPP_VideoDecoder_Dev*>(instance->module()-> 39 static_cast<const PPP_VideoDecoder_Dev*>(instance->module()->
44 GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE)); 40 GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE));
45 } 41 }
46 42
47 PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { 43 PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() {
48 } 44 }
49 45
50 PPB_VideoDecoder_API* PPB_VideoDecoder_Impl::AsPPB_VideoDecoder_API() { 46 PPB_VideoDecoder_API* PPB_VideoDecoder_Impl::AsPPB_VideoDecoder_API() {
51 return this; 47 return this;
52 } 48 }
53 49
54 // static 50 // static
55 PP_Resource PPB_VideoDecoder_Impl::Create(PluginInstance* instance, 51 PP_Resource PPB_VideoDecoder_Impl::Create(PluginInstance* instance,
56 PP_Resource context3d_id, 52 PP_Resource context3d_id,
57 const PP_VideoConfigElement* config) { 53 const PP_VideoConfigElement* config) {
58 scoped_refptr<PPB_VideoDecoder_Impl> decoder( 54 scoped_refptr<PPB_VideoDecoder_Impl> decoder(
59 new PPB_VideoDecoder_Impl(instance)); 55 new PPB_VideoDecoder_Impl(instance));
60 if (decoder->Init(context3d_id, config)) 56 if (decoder->Init(context3d_id, config))
61 return decoder->GetReference(); 57 return decoder->GetReference();
62 return 0; 58 return 0;
63 } 59 }
64 60
65 bool PPB_VideoDecoder_Impl::Init(PP_Resource context3d_id, 61 bool PPB_VideoDecoder_Impl::Init(PP_Resource context3d_id,
66 const PP_VideoConfigElement* config) { 62 const PP_VideoConfigElement* config) {
67 if (!instance() || !context3d_id || !config) 63 if(!instance() || !::ppapi::VideoDecoderImpl::Init(context3d_id, config))
Ami GONE FROM CHROMIUM 2011/08/02 00:49:08 How can instance() be NULL, do you know?
vrk (LEFT CHROMIUM) 2011/08/03 22:05:22 It appears it can't be -- when ResourceCreationImp
68 return false; 64 return false;
69 65
70 EnterResourceNoLock<PPB_Context3D_API> enter(context3d_id, true); 66 EnterResourceNoLock<PPB_Context3D_API> enter_context(context3d_id, true);
71 if (enter.failed()) 67 DCHECK(enter_context.succeeded());
Ami GONE FROM CHROMIUM 2011/08/02 00:49:08 I'm not entirely sure about this; it's only correc
vrk (LEFT CHROMIUM) 2011/08/03 19:04:30 Agreed. To also address piman's concern w/ the dou
68
69 std::vector<int32> copied;
70 if (!CopyConfigsToVector(config, &copied))
72 return false; 71 return false;
72
73 PPB_Context3D_Impl* context3d = 73 PPB_Context3D_Impl* context3d =
74 static_cast<PPB_Context3D_Impl*>(enter.object()); 74 static_cast<PPB_Context3D_Impl*>(enter_context.object());
75
76 context3d_id_ = context3d_id;
77 ResourceTracker::Get()->AddRefResource(context3d_id_);
78 75
79 int command_buffer_route_id = 76 int command_buffer_route_id =
80 context3d->platform_context()->GetCommandBufferRouteId(); 77 context3d->platform_context()->GetCommandBufferRouteId();
81 if (command_buffer_route_id == 0) 78 if (command_buffer_route_id == 0)
82 return false; 79 return false;
83 platform_video_decoder_ = instance()->delegate()->CreateVideoDecoder( 80 platform_video_decoder_ = instance()->delegate()->CreateVideoDecoder(
84 this, command_buffer_route_id); 81 this, command_buffer_route_id);
85
86 gles2_impl_ = context3d->gles2_impl();
87
88 if (!platform_video_decoder_) 82 if (!platform_video_decoder_)
89 return false; 83 return false;
90 84
91 std::vector<uint32> copied;
92 // TODO(fischman,vrk): this is completely broken in that it fails to account
93 // for the semantic distinction between keys and values; it is certainly
94 // possible for a value to show up as 0, and that shouldn't terminate the
95 // config vector. Only a *key* of 0 should do so.
96 // TODO(vrk): This is assuming PP_VideoAttributeDictionary and
97 // VideoAttributeKey have identical enum values. There is no compiler
98 // assert to guarantee this. We either need to add such asserts or
99 // merge PP_VideoAttributeDictionary and VideoAttributeKey.
100 for (const PP_VideoConfigElement* current = config;
101 *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR; ++current) {
102 copied.push_back(static_cast<uint32>(*current));
103 }
104
105 FlushCommandBuffer(); 85 FlushCommandBuffer();
106 return platform_video_decoder_->Initialize(copied); 86 return platform_video_decoder_->Initialize(copied);
107 } 87 }
108 88
109 int32_t PPB_VideoDecoder_Impl::Decode( 89 int32_t PPB_VideoDecoder_Impl::Decode(
110 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, 90 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
111 PP_CompletionCallback callback) { 91 PP_CompletionCallback callback) {
112 if (!platform_video_decoder_) 92 if (!platform_video_decoder_)
113 return PP_ERROR_BADRESOURCE; 93 return PP_ERROR_BADRESOURCE;
114 94
115 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); 95 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true);
116 if (enter.failed()) 96 if (enter.failed())
117 return PP_ERROR_FAILED; 97 return PP_ERROR_FAILED;
118 98
119 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); 99 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object());
120 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, 100 media::BitstreamBuffer decode_buffer(bitstream_buffer->id,
121 buffer->shared_memory()->handle(), 101 buffer->shared_memory()->handle(),
122 static_cast<size_t>(buffer->size())); 102 static_cast<size_t>(buffer->size()));
123 CHECK(bitstream_buffer_callbacks_.insert(std::make_pair( 103 AddBitstreamBufferCallback(bitstream_buffer->id, callback);
124 bitstream_buffer->id, callback)).second);
125 104
126 FlushCommandBuffer(); 105 FlushCommandBuffer();
127 platform_video_decoder_->Decode(decode_buffer); 106 platform_video_decoder_->Decode(decode_buffer);
128 return PP_OK_COMPLETIONPENDING; 107 return PP_OK_COMPLETIONPENDING;
129 } 108 }
130 109
131 void PPB_VideoDecoder_Impl::AssignPictureBuffers( 110 void PPB_VideoDecoder_Impl::AssignPictureBuffers(
132 uint32_t no_of_buffers, 111 uint32_t no_of_buffers,
133 const PP_PictureBuffer_Dev* buffers) { 112 const PP_PictureBuffer_Dev* buffers) {
134 if (!platform_video_decoder_) 113 if (!platform_video_decoder_)
(...skipping 19 matching lines...) Expand all
154 133
155 FlushCommandBuffer(); 134 FlushCommandBuffer();
156 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); 135 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id);
157 } 136 }
158 137
159 int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { 138 int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) {
160 if (!platform_video_decoder_) 139 if (!platform_video_decoder_)
161 return PP_ERROR_BADRESOURCE; 140 return PP_ERROR_BADRESOURCE;
162 141
163 // Store the callback to be called when Flush() is done. 142 // Store the callback to be called when Flush() is done.
164 // TODO(fischman,vrk): consider implications of already-outstanding callback. 143 // TODO(fischman,vrk): consider implications of already-outstanding callback.
Ami GONE FROM CHROMIUM 2011/08/02 00:49:08 This TODO (and its sibling below) don't belong her
vrk (LEFT CHROMIUM) 2011/08/03 19:04:30 Done.
165 flush_callback_ = callback; 144 SetFlushCallback(callback);
166 145
167 FlushCommandBuffer(); 146 FlushCommandBuffer();
168 platform_video_decoder_->Flush(); 147 platform_video_decoder_->Flush();
169 return PP_OK_COMPLETIONPENDING; 148 return PP_OK_COMPLETIONPENDING;
170 } 149 }
171 150
172 int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) { 151 int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) {
173 if (!platform_video_decoder_) 152 if (!platform_video_decoder_)
174 return PP_ERROR_BADRESOURCE; 153 return PP_ERROR_BADRESOURCE;
175 154
176 // Store the callback to be called when Reset() is done. 155 // Store the callback to be called when Reset() is done.
177 // TODO(fischman,vrk): consider implications of already-outstanding callback. 156 // TODO(fischman,vrk): consider implications of already-outstanding callback.
178 reset_callback_ = callback; 157 SetResetCallback(callback);
179 158
180 FlushCommandBuffer(); 159 FlushCommandBuffer();
181 platform_video_decoder_->Reset(); 160 platform_video_decoder_->Reset();
182 return PP_OK_COMPLETIONPENDING; 161 return PP_OK_COMPLETIONPENDING;
183 } 162 }
184 163
185 void PPB_VideoDecoder_Impl::Destroy() { 164 void PPB_VideoDecoder_Impl::Destroy() {
186 if (!platform_video_decoder_) 165 if (!platform_video_decoder_)
187 return; 166 return;
188 167
189 FlushCommandBuffer(); 168 FlushCommandBuffer();
190 platform_video_decoder_->Destroy(); 169 platform_video_decoder_->Destroy();
191 gles2_impl_ = NULL;
192 if (context3d_id_)
193 ResourceTracker::Get()->UnrefResource(context3d_id_);
194 platform_video_decoder_ = NULL; 170 platform_video_decoder_ = NULL;
195 ppp_videodecoder_ = NULL; 171 ppp_videodecoder_ = NULL;
172
173 ::ppapi::VideoDecoderImpl::Destroy();
Ami GONE FROM CHROMIUM 2011/08/02 00:49:08 Is it obvious why this belongs after the 2 =NULL's
vrk (LEFT CHROMIUM) 2011/08/03 19:04:30 Talked in person, done.
196 } 174 }
197 175
198 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( 176 void PPB_VideoDecoder_Impl::ProvidePictureBuffers(
199 uint32 requested_num_of_buffers, const gfx::Size& dimensions) { 177 uint32 requested_num_of_buffers, const gfx::Size& dimensions) {
200 if (!ppp_videodecoder_) 178 if (!ppp_videodecoder_)
201 return; 179 return;
202 180
203 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); 181 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height());
204 ScopedResourceId resource(this); 182 ScopedResourceId resource(this);
205 ppp_videodecoder_->ProvidePictureBuffers( 183 ppp_videodecoder_->ProvidePictureBuffers(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 ScopedResourceId resource(this); 222 ScopedResourceId resource(this);
245 // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and 223 // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and
246 // PP_VideoDecodeError_Dev have identical enum values. There is no compiler 224 // PP_VideoDecodeError_Dev have identical enum values. There is no compiler
247 // assert to guarantee this. We either need to add such asserts or 225 // assert to guarantee this. We either need to add such asserts or
248 // merge these two enums. 226 // merge these two enums.
249 ppp_videodecoder_->NotifyError(instance()->pp_instance(), resource.id, 227 ppp_videodecoder_->NotifyError(instance()->pp_instance(), resource.id,
250 static_cast<PP_VideoDecodeError_Dev>(error)); 228 static_cast<PP_VideoDecodeError_Dev>(error));
251 } 229 }
252 230
253 void PPB_VideoDecoder_Impl::NotifyResetDone() { 231 void PPB_VideoDecoder_Impl::NotifyResetDone() {
254 if (reset_callback_.func == NULL) 232 RunResetCallback();
255 return;
256
257 // Call the callback that was stored to be called when Reset is done.
258 PP_RunAndClearCompletionCallback(&reset_callback_, PP_OK);
259 } 233 }
260 234
261 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( 235 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer(
262 int32 bitstream_buffer_id) { 236 int32 bitstream_buffer_id) {
263 CallbackById::iterator it = 237 RunBitstreamBufferCallback(bitstream_buffer_id);
264 bitstream_buffer_callbacks_.find(bitstream_buffer_id);
265 DCHECK(it != bitstream_buffer_callbacks_.end());
266 PP_CompletionCallback cc = it->second;
267 bitstream_buffer_callbacks_.erase(it);
268 PP_RunCompletionCallback(&cc, PP_OK);
269 } 238 }
270 239
271 void PPB_VideoDecoder_Impl::NotifyFlushDone() { 240 void PPB_VideoDecoder_Impl::NotifyFlushDone() {
272 if (flush_callback_.func == NULL) 241 RunFlushCallback();
273 return;
274
275 // Call the callback that was stored to be called when Flush is done.
276 PP_RunAndClearCompletionCallback(&flush_callback_, PP_OK);
277 } 242 }
278 243
279 void PPB_VideoDecoder_Impl::NotifyInitializeDone() { 244 void PPB_VideoDecoder_Impl::NotifyInitializeDone() {
280 NOTREACHED() << "PlatformVideoDecoder::Initialize() is synchronous!"; 245 NOTREACHED() << "PlatformVideoDecoder::Initialize() is synchronous!";
281 } 246 }
282 247
283 void PPB_VideoDecoder_Impl::FlushCommandBuffer() {
284 // For the out-of-process case, |gles2_impl_| will be NULL in the renderer
285 // process. The VideoDecoder_Proxy is charged with the responsibility of
286 // doing this Flush() in the analogous places in the plugin process.
287 if (gles2_impl_)
288 gles2_impl_->Flush();
289 }
290
291 } // namespace ppapi 248 } // namespace ppapi
292 } // namespace webkit 249 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698