| OLD | NEW |
| 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 18 matching lines...) Expand all Loading... |
| 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 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 38 context3d_id_(0), | 38 context3d_id_(0), |
| 39 destroy_callback_(PP_BlockUntilComplete()), | |
| 40 flush_callback_(PP_BlockUntilComplete()), | 39 flush_callback_(PP_BlockUntilComplete()), |
| 41 reset_callback_(PP_BlockUntilComplete()) { | 40 reset_callback_(PP_BlockUntilComplete()) { |
| 42 ppp_videodecoder_ = | 41 ppp_videodecoder_ = |
| 43 static_cast<const PPP_VideoDecoder_Dev*>(instance->module()-> | 42 static_cast<const PPP_VideoDecoder_Dev*>(instance->module()-> |
| 44 GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE)); | 43 GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE)); |
| 45 } | 44 } |
| 46 | 45 |
| 47 PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { | 46 PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { |
| 48 if (context3d_id_) | 47 if (context3d_id_) |
| 49 ResourceTracker::Get()->UnrefResource(context3d_id_); | 48 ResourceTracker::Get()->UnrefResource(context3d_id_); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 69 PPB_Context3D_Impl* context3d = | 68 PPB_Context3D_Impl* context3d = |
| 70 static_cast<PPB_Context3D_Impl*>(enter.object()); | 69 static_cast<PPB_Context3D_Impl*>(enter.object()); |
| 71 | 70 |
| 72 context3d_id_ = context_id; | 71 context3d_id_ = context_id; |
| 73 ResourceTracker::Get()->AddRefResource(context3d_id_); | 72 ResourceTracker::Get()->AddRefResource(context3d_id_); |
| 74 int command_buffer_route_id = | 73 int command_buffer_route_id = |
| 75 context3d->platform_context()->GetCommandBufferRouteId(); | 74 context3d->platform_context()->GetCommandBufferRouteId(); |
| 76 if (command_buffer_route_id == 0) | 75 if (command_buffer_route_id == 0) |
| 77 return PP_ERROR_FAILED; | 76 return PP_ERROR_FAILED; |
| 78 | 77 |
| 79 platform_video_decoder_.reset( | 78 platform_video_decoder_ = instance()->delegate()->CreateVideoDecoder( |
| 80 instance()->delegate()->CreateVideoDecoder( | 79 this, command_buffer_route_id, context3d->gles2_impl()->helper()); |
| 81 this, command_buffer_route_id, context3d->gles2_impl()->helper())); | |
| 82 | 80 |
| 83 if (!platform_video_decoder_.get()) | 81 if (!platform_video_decoder_) |
| 84 return PP_ERROR_FAILED; | 82 return PP_ERROR_FAILED; |
| 85 | 83 |
| 86 std::vector<uint32> copied; | 84 std::vector<uint32> copied; |
| 87 // TODO(fischman,vrk): this is completely broken in that it fails to account | 85 // TODO(fischman,vrk): this is completely broken in that it fails to account |
| 88 // for the semantic distinction between keys and values; it is certainly | 86 // for the semantic distinction between keys and values; it is certainly |
| 89 // possible for a value to show up as 0, and that shouldn't terminate the | 87 // possible for a value to show up as 0, and that shouldn't terminate the |
| 90 // config vector. Only a *key* of 0 should do so. | 88 // config vector. Only a *key* of 0 should do so. |
| 91 // TODO(vrk): This is assuming PP_VideoAttributeDictionary and | 89 // TODO(vrk): This is assuming PP_VideoAttributeDictionary and |
| 92 // VideoAttributeKey have identical enum values. There is no compiler | 90 // VideoAttributeKey have identical enum values. There is no compiler |
| 93 // assert to guarantee this. We either need to add such asserts or | 91 // assert to guarantee this. We either need to add such asserts or |
| 94 // merge PP_VideoAttributeDictionary and VideoAttributeKey. | 92 // merge PP_VideoAttributeDictionary and VideoAttributeKey. |
| 95 for (const PP_VideoConfigElement* current = decoder_config; | 93 for (const PP_VideoConfigElement* current = decoder_config; |
| 96 *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR; ++current) { | 94 *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR; ++current) { |
| 97 copied.push_back(static_cast<uint32>(*current)); | 95 copied.push_back(static_cast<uint32>(*current)); |
| 98 } | 96 } |
| 99 | 97 |
| 100 if (platform_video_decoder_->Initialize(copied)) { | 98 if (platform_video_decoder_->Initialize(copied)) { |
| 101 initialization_callback_ = callback; | 99 initialization_callback_ = callback; |
| 102 return PP_OK_COMPLETIONPENDING; | 100 return PP_OK_COMPLETIONPENDING; |
| 103 } else { | 101 } else { |
| 104 return PP_ERROR_FAILED; | 102 return PP_ERROR_FAILED; |
| 105 } | 103 } |
| 106 } | 104 } |
| 107 | 105 |
| 108 int32_t PPB_VideoDecoder_Impl::Decode( | 106 int32_t PPB_VideoDecoder_Impl::Decode( |
| 109 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, | 107 const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, |
| 110 PP_CompletionCallback callback) { | 108 PP_CompletionCallback callback) { |
| 111 if (!platform_video_decoder_.get()) | 109 if (!platform_video_decoder_) |
| 112 return PP_ERROR_BADRESOURCE; | 110 return PP_ERROR_BADRESOURCE; |
| 113 | 111 |
| 114 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); | 112 EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); |
| 115 if (enter.failed()) | 113 if (enter.failed()) |
| 116 return PP_ERROR_FAILED; | 114 return PP_ERROR_FAILED; |
| 117 | 115 |
| 118 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); | 116 PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); |
| 119 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, | 117 media::BitstreamBuffer decode_buffer(bitstream_buffer->id, |
| 120 buffer->shared_memory()->handle(), | 118 buffer->shared_memory()->handle(), |
| 121 static_cast<size_t>(buffer->size())); | 119 static_cast<size_t>(buffer->size())); |
| 122 CHECK(bitstream_buffer_callbacks_.insert(std::make_pair( | 120 CHECK(bitstream_buffer_callbacks_.insert(std::make_pair( |
| 123 bitstream_buffer->id, callback)).second); | 121 bitstream_buffer->id, callback)).second); |
| 124 | 122 |
| 125 platform_video_decoder_->Decode(decode_buffer); | 123 platform_video_decoder_->Decode(decode_buffer); |
| 126 return PP_OK_COMPLETIONPENDING; | 124 return PP_OK_COMPLETIONPENDING; |
| 127 } | 125 } |
| 128 | 126 |
| 129 void PPB_VideoDecoder_Impl::AssignGLESBuffers( | 127 void PPB_VideoDecoder_Impl::AssignGLESBuffers( |
| 130 uint32_t no_of_buffers, | 128 uint32_t no_of_buffers, |
| 131 const PP_GLESBuffer_Dev* buffers) { | 129 const PP_GLESBuffer_Dev* buffers) { |
| 132 if (!platform_video_decoder_.get()) | 130 if (!platform_video_decoder_) |
| 133 return; | 131 return; |
| 134 | 132 |
| 135 std::vector<media::GLESBuffer> wrapped_buffers; | 133 std::vector<media::GLESBuffer> wrapped_buffers; |
| 136 for (uint32 i = 0; i < no_of_buffers; i++) { | 134 for (uint32 i = 0; i < no_of_buffers; i++) { |
| 137 PP_GLESBuffer_Dev in_buf = buffers[i]; | 135 PP_GLESBuffer_Dev in_buf = buffers[i]; |
| 138 media::GLESBuffer buffer( | 136 media::GLESBuffer buffer( |
| 139 in_buf.info.id, | 137 in_buf.info.id, |
| 140 gfx::Size(in_buf.info.size.width, in_buf.info.size.height), | 138 gfx::Size(in_buf.info.size.width, in_buf.info.size.height), |
| 141 in_buf.texture_id); | 139 in_buf.texture_id); |
| 142 wrapped_buffers.push_back(buffer); | 140 wrapped_buffers.push_back(buffer); |
| 143 } | 141 } |
| 144 platform_video_decoder_->AssignGLESBuffers(wrapped_buffers); | 142 platform_video_decoder_->AssignGLESBuffers(wrapped_buffers); |
| 145 } | 143 } |
| 146 | 144 |
| 147 void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { | 145 void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { |
| 148 if (!platform_video_decoder_.get()) | 146 if (!platform_video_decoder_) |
| 149 return; | 147 return; |
| 150 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); | 148 platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); |
| 151 } | 149 } |
| 152 | 150 |
| 153 int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { | 151 int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { |
| 154 if (!platform_video_decoder_.get()) | 152 if (!platform_video_decoder_) |
| 155 return PP_ERROR_BADRESOURCE; | 153 return PP_ERROR_BADRESOURCE; |
| 156 | 154 |
| 157 // Store the callback to be called when Flush() is done. | 155 // Store the callback to be called when Flush() is done. |
| 158 // TODO(fischman,vrk): consider implications of already-outstanding callback. | 156 // TODO(fischman,vrk): consider implications of already-outstanding callback. |
| 159 flush_callback_ = callback; | 157 flush_callback_ = callback; |
| 160 | 158 |
| 161 platform_video_decoder_->Flush(); | 159 platform_video_decoder_->Flush(); |
| 162 return PP_OK_COMPLETIONPENDING; | 160 return PP_OK_COMPLETIONPENDING; |
| 163 } | 161 } |
| 164 | 162 |
| 165 int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) { | 163 int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) { |
| 166 if (!platform_video_decoder_.get()) | 164 if (!platform_video_decoder_) |
| 167 return PP_ERROR_BADRESOURCE; | 165 return PP_ERROR_BADRESOURCE; |
| 168 | 166 |
| 169 // Store the callback to be called when Reset() is done. | 167 // Store the callback to be called when Reset() is done. |
| 170 // TODO(fischman,vrk): consider implications of already-outstanding callback. | 168 // TODO(fischman,vrk): consider implications of already-outstanding callback. |
| 171 reset_callback_ = callback; | 169 reset_callback_ = callback; |
| 172 | 170 |
| 173 platform_video_decoder_->Reset(); | 171 platform_video_decoder_->Reset(); |
| 174 return PP_OK_COMPLETIONPENDING; | 172 return PP_OK_COMPLETIONPENDING; |
| 175 } | 173 } |
| 176 | 174 |
| 177 int32_t PPB_VideoDecoder_Impl::Destroy(PP_CompletionCallback callback) { | 175 void PPB_VideoDecoder_Impl::Destroy() { |
| 178 if (!platform_video_decoder_.get()) | 176 if (!platform_video_decoder_) |
| 179 return PP_ERROR_BADRESOURCE; | 177 return; |
| 180 | |
| 181 // Store the callback to be called when Destroy() is done. | |
| 182 // TODO(fischman,vrk): consider implications of already-outstanding callback. | |
| 183 destroy_callback_ = callback; | |
| 184 | |
| 185 platform_video_decoder_->Destroy(); | 178 platform_video_decoder_->Destroy(); |
| 186 return PP_OK_COMPLETIONPENDING; | |
| 187 } | 179 } |
| 188 | 180 |
| 189 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( | 181 void PPB_VideoDecoder_Impl::ProvidePictureBuffers( |
| 190 uint32 requested_num_of_buffers, | 182 uint32 requested_num_of_buffers, |
| 191 const gfx::Size& dimensions, | 183 const gfx::Size& dimensions, |
| 192 media::VideoDecodeAccelerator::MemoryType type) { | 184 media::VideoDecodeAccelerator::MemoryType type) { |
| 193 if (!ppp_videodecoder_) | 185 if (!ppp_videodecoder_) |
| 194 return; | 186 return; |
| 195 | 187 |
| 196 // TODO(vrk): Compiler assert or use switch statement instead of making | 188 // TODO(vrk): Compiler assert or use switch statement instead of making |
| 197 // a blind cast. | 189 // a blind cast. |
| 198 PP_PictureBufferType_Dev out_type = | 190 PP_PictureBufferType_Dev out_type = |
| 199 static_cast<PP_PictureBufferType_Dev>(type); | 191 static_cast<PP_PictureBufferType_Dev>(type); |
| 200 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); | 192 PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); |
| 201 ScopedResourceId resource(this); | |
| 202 ppp_videodecoder_->ProvidePictureBuffers( | 193 ppp_videodecoder_->ProvidePictureBuffers( |
| 203 instance()->pp_instance(), resource.id, requested_num_of_buffers, | 194 instance()->pp_instance(), requested_num_of_buffers, out_dim, out_type); |
| 204 out_dim, out_type); | |
| 205 } | 195 } |
| 206 | 196 |
| 207 void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { | 197 void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { |
| 208 if (!ppp_videodecoder_) | 198 if (!ppp_videodecoder_) |
| 209 return; | 199 return; |
| 210 | 200 |
| 211 ScopedResourceId resource(this); | |
| 212 PP_Picture_Dev output; | 201 PP_Picture_Dev output; |
| 213 output.picture_buffer_id = picture.picture_buffer_id(); | 202 output.picture_buffer_id = picture.picture_buffer_id(); |
| 214 output.bitstream_buffer_id = picture.bitstream_buffer_id(); | 203 output.bitstream_buffer_id = picture.bitstream_buffer_id(); |
| 215 output.visible_size = PP_MakeSize(picture.visible_size().width(), | 204 output.visible_size = PP_MakeSize(picture.visible_size().width(), |
| 216 picture.visible_size().height()); | 205 picture.visible_size().height()); |
| 217 output.decoded_size = PP_MakeSize(picture.decoded_size().width(), | 206 output.decoded_size = PP_MakeSize(picture.decoded_size().width(), |
| 218 picture.decoded_size().height()); | 207 picture.decoded_size().height()); |
| 219 ppp_videodecoder_->PictureReady( | 208 ppp_videodecoder_->PictureReady(instance()->pp_instance(), output); |
| 220 instance()->pp_instance(), resource.id, output); | |
| 221 } | 209 } |
| 222 | 210 |
| 223 void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { | 211 void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { |
| 224 if (!ppp_videodecoder_) | 212 if (!ppp_videodecoder_) |
| 225 return; | 213 return; |
| 226 | 214 |
| 227 ScopedResourceId resource(this); | |
| 228 ppp_videodecoder_->DismissPictureBuffer( | 215 ppp_videodecoder_->DismissPictureBuffer( |
| 229 instance()->pp_instance(), resource.id, picture_buffer_id); | 216 instance()->pp_instance(), picture_buffer_id); |
| 230 } | 217 } |
| 231 | 218 |
| 232 void PPB_VideoDecoder_Impl::NotifyEndOfStream() { | 219 void PPB_VideoDecoder_Impl::NotifyEndOfStream() { |
| 233 if (!ppp_videodecoder_) | 220 if (!ppp_videodecoder_) |
| 234 return; | 221 return; |
| 235 | 222 |
| 236 ScopedResourceId resource(this); | 223 ppp_videodecoder_->EndOfStream(instance()->pp_instance()); |
| 237 ppp_videodecoder_->EndOfStream(instance()->pp_instance(), resource.id); | |
| 238 } | 224 } |
| 239 | 225 |
| 240 void PPB_VideoDecoder_Impl::NotifyError( | 226 void PPB_VideoDecoder_Impl::NotifyError( |
| 241 media::VideoDecodeAccelerator::Error error) { | 227 media::VideoDecodeAccelerator::Error error) { |
| 242 if (!ppp_videodecoder_) | 228 if (!ppp_videodecoder_) |
| 243 return; | 229 return; |
| 244 | 230 |
| 245 ScopedResourceId resource(this); | |
| 246 // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and | 231 // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and |
| 247 // PP_VideoDecodeError_Dev have identical enum values. There is no compiler | 232 // PP_VideoDecodeError_Dev have identical enum values. There is no compiler |
| 248 // assert to guarantee this. We either need to add such asserts or | 233 // assert to guarantee this. We either need to add such asserts or |
| 249 // merge these two enums. | 234 // merge these two enums. |
| 250 ppp_videodecoder_->NotifyError(instance()->pp_instance(), resource.id, | 235 ppp_videodecoder_->NotifyError(instance()->pp_instance(), |
| 251 static_cast<PP_VideoDecodeError_Dev>(error)); | 236 static_cast<PP_VideoDecodeError_Dev>(error)); |
| 252 } | 237 } |
| 253 | 238 |
| 254 void PPB_VideoDecoder_Impl::NotifyResetDone() { | 239 void PPB_VideoDecoder_Impl::NotifyResetDone() { |
| 255 if (reset_callback_.func == NULL) | 240 if (reset_callback_.func == NULL) |
| 256 return; | 241 return; |
| 257 | 242 |
| 258 // Call the callback that was stored to be called when Reset is done. | 243 // Call the callback that was stored to be called when Reset is done. |
| 259 PP_RunAndClearCompletionCallback(&reset_callback_, PP_OK); | 244 PP_RunAndClearCompletionCallback(&reset_callback_, PP_OK); |
| 260 } | 245 } |
| 261 | 246 |
| 262 void PPB_VideoDecoder_Impl::NotifyDestroyDone() { | |
| 263 if (destroy_callback_.func == NULL) | |
| 264 return; | |
| 265 | |
| 266 // Call the callback that was stored to be called when Destroy is done. | |
| 267 PP_RunAndClearCompletionCallback(&destroy_callback_, PP_OK); | |
| 268 } | |
| 269 | |
| 270 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( | 247 void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( |
| 271 int32 bitstream_buffer_id) { | 248 int32 bitstream_buffer_id) { |
| 272 CallbackById::iterator it = | 249 CallbackById::iterator it = |
| 273 bitstream_buffer_callbacks_.find(bitstream_buffer_id); | 250 bitstream_buffer_callbacks_.find(bitstream_buffer_id); |
| 274 DCHECK(it != bitstream_buffer_callbacks_.end()); | 251 DCHECK(it != bitstream_buffer_callbacks_.end()); |
| 275 PP_CompletionCallback cc = it->second; | 252 PP_CompletionCallback cc = it->second; |
| 276 bitstream_buffer_callbacks_.erase(it); | 253 bitstream_buffer_callbacks_.erase(it); |
| 277 PP_RunCompletionCallback(&cc, PP_OK); | 254 PP_RunCompletionCallback(&cc, PP_OK); |
| 278 } | 255 } |
| 279 | 256 |
| 280 void PPB_VideoDecoder_Impl::NotifyFlushDone() { | 257 void PPB_VideoDecoder_Impl::NotifyFlushDone() { |
| 281 if (flush_callback_.func == NULL) | 258 if (flush_callback_.func == NULL) |
| 282 return; | 259 return; |
| 283 | 260 |
| 284 // Call the callback that was stored to be called when Flush is done. | 261 // Call the callback that was stored to be called when Flush is done. |
| 285 PP_RunAndClearCompletionCallback(&flush_callback_, PP_OK); | 262 PP_RunAndClearCompletionCallback(&flush_callback_, PP_OK); |
| 286 } | 263 } |
| 287 | 264 |
| 288 void PPB_VideoDecoder_Impl::NotifyInitializeDone() { | 265 void PPB_VideoDecoder_Impl::NotifyInitializeDone() { |
| 289 if (initialization_callback_.func == NULL) | 266 if (initialization_callback_.func == NULL) |
| 290 return; | 267 return; |
| 291 | 268 |
| 292 PP_RunAndClearCompletionCallback(&initialization_callback_, PP_OK); | 269 PP_RunAndClearCompletionCallback(&initialization_callback_, PP_OK); |
| 293 } | 270 } |
| 294 | 271 |
| 295 } // namespace ppapi | 272 } // namespace ppapi |
| 296 } // namespace webkit | 273 } // namespace webkit |
| OLD | NEW |