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