| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/media/crypto/ppapi/clear_key_cdm.h" | 5 #include "webkit/media/crypto/ppapi/clear_key_cdm.h" | 
| 6 | 6 | 
| 7 #include <vector> | 7 #include <vector> | 
| 8 | 8 | 
| 9 #include "base/bind.h" | 9 #include "base/bind.h" | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| 11 #include "base/time.h" | 11 #include "base/time.h" | 
| 12 #include "media/base/decoder_buffer.h" | 12 #include "media/base/decoder_buffer.h" | 
| 13 | 13 | 
|  | 14 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 
|  | 15 #include "base/at_exit.h" | 
|  | 16 #include "base/file_path.h" | 
|  | 17 #include "base/path_service.h" | 
|  | 18 #include "media/base/media.h" | 
|  | 19 #include "webkit/media/crypto/ppapi/ffmpeg_cdm_video_decoder.h" | 
|  | 20 | 
|  | 21 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must | 
|  | 22 // exist before the call to InitializeFFmpegLibraries(). This should no longer | 
|  | 23 // be required after http://crbug.com/91970 because we'll be able to get rid of | 
|  | 24 // InitializeFFmpegLibraries(). | 
|  | 25 #if !defined COMPONENT_BUILD | 
|  | 26 static base::AtExitManager g_at_exit_manager; | 
|  | 27 #endif | 
|  | 28 | 
|  | 29 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized| | 
|  | 30 // are required for running in the sandbox, and should no longer be required | 
|  | 31 // after http://crbug.com/91970 is fixed. | 
|  | 32 static bool InitializeFFmpegLibraries() { | 
|  | 33   FilePath file_path; | 
|  | 34   CHECK(PathService::Get(base::DIR_EXE, &file_path)); | 
|  | 35   CHECK(media::InitializeMediaLibrary(file_path)); | 
|  | 36   return true; | 
|  | 37 } | 
|  | 38 | 
|  | 39 static bool g_cdm_module_initialized = InitializeFFmpegLibraries(); | 
|  | 40 #endif  // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | 
|  | 41 | 
| 14 static const char kClearKeyCdmVersion[] = "0.1.0.0"; | 42 static const char kClearKeyCdmVersion[] = "0.1.0.0"; | 
| 15 | 43 | 
| 16 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( | 44 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( | 
| 17     const cdm::InputBuffer& input_buffer) { | 45     const cdm::InputBuffer& input_buffer) { | 
| 18   DCHECK(input_buffer.data); | 46   DCHECK(input_buffer.data); | 
| 19   // TODO(tomfinegan): Get rid of this copy. | 47   // TODO(tomfinegan): Get rid of this copy. | 
| 20   scoped_refptr<media::DecoderBuffer> output_buffer = | 48   scoped_refptr<media::DecoderBuffer> output_buffer = | 
| 21       media::DecoderBuffer::CopyFrom(input_buffer.data, input_buffer.data_size); | 49       media::DecoderBuffer::CopyFrom(input_buffer.data, input_buffer.data_size); | 
| 22 | 50 | 
| 23   std::vector<media::SubsampleEntry> subsamples; | 51   std::vector<media::SubsampleEntry> subsamples; | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 58 template<typename Type> | 86 template<typename Type> | 
| 59 static Type* AllocateAndCopy(const Type* data, int size) { | 87 static Type* AllocateAndCopy(const Type* data, int size) { | 
| 60   COMPILE_ASSERT(sizeof(Type) == 1, type_size_is_not_one); | 88   COMPILE_ASSERT(sizeof(Type) == 1, type_size_is_not_one); | 
| 61   Type* copy = new Type[size]; | 89   Type* copy = new Type[size]; | 
| 62   memcpy(copy, data, size); | 90   memcpy(copy, data, size); | 
| 63   return copy; | 91   return copy; | 
| 64 } | 92 } | 
| 65 | 93 | 
| 66 cdm::ContentDecryptionModule* CreateCdmInstance( | 94 cdm::ContentDecryptionModule* CreateCdmInstance( | 
| 67     cdm::Allocator* allocator, cdm::CdmHost* host) { | 95     cdm::Allocator* allocator, cdm::CdmHost* host) { | 
|  | 96   DVLOG(1) << "CreateCdmInstance()"; | 
| 68   return new webkit_media::ClearKeyCdm(allocator, host); | 97   return new webkit_media::ClearKeyCdm(allocator, host); | 
| 69 } | 98 } | 
| 70 | 99 | 
| 71 void DestroyCdmInstance(cdm::ContentDecryptionModule* instance) { | 100 void DestroyCdmInstance(cdm::ContentDecryptionModule* instance) { | 
|  | 101   DVLOG(1) << "DestroyCdmInstance()"; | 
| 72   delete instance; | 102   delete instance; | 
| 73 } | 103 } | 
| 74 | 104 | 
| 75 const char* GetCdmVersion() { | 105 const char* GetCdmVersion() { | 
| 76   return kClearKeyCdmVersion; | 106   return kClearKeyCdmVersion; | 
| 77 } | 107 } | 
| 78 | 108 | 
| 79 namespace webkit_media { | 109 namespace webkit_media { | 
| 80 | 110 | 
| 81 ClearKeyCdm::Client::Client() : status_(kKeyError), key_message_length_(0) {} | 111 ClearKeyCdm::Client::Client() : status_(kKeyError), key_message_length_(0) {} | 
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 237 } | 267 } | 
| 238 | 268 | 
| 239 cdm::Status ClearKeyCdm::InitializeAudioDecoder( | 269 cdm::Status ClearKeyCdm::InitializeAudioDecoder( | 
| 240     const cdm::AudioDecoderConfig& audio_decoder_config) { | 270     const cdm::AudioDecoderConfig& audio_decoder_config) { | 
| 241   NOTIMPLEMENTED(); | 271   NOTIMPLEMENTED(); | 
| 242   return cdm::kSessionError; | 272   return cdm::kSessionError; | 
| 243 } | 273 } | 
| 244 | 274 | 
| 245 cdm::Status ClearKeyCdm::InitializeVideoDecoder( | 275 cdm::Status ClearKeyCdm::InitializeVideoDecoder( | 
| 246     const cdm::VideoDecoderConfig& video_decoder_config) { | 276     const cdm::VideoDecoderConfig& video_decoder_config) { | 
| 247 #if !defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | 277 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 
|  | 278   if (!video_decoder_) | 
|  | 279     video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_)); | 
|  | 280 | 
|  | 281   if (!video_decoder_->Initialize(video_decoder_config)) | 
|  | 282     return cdm::kSessionError; | 
|  | 283 | 
|  | 284   return cdm::kSuccess; | 
|  | 285 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | 
|  | 286   video_size_ = video_decoder_config.coded_size; | 
|  | 287   return cdm::kSuccess; | 
|  | 288 #else | 
| 248   NOTIMPLEMENTED(); | 289   NOTIMPLEMENTED(); | 
| 249   return cdm::kSessionError; | 290   return cdm::kSessionError; | 
| 250 #else | 291 #endif  // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | 
| 251   video_size_ = video_decoder_config.coded_size; | 292 | 
| 252   return cdm::kSuccess; |  | 
| 253 #endif  // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER |  | 
| 254 } | 293 } | 
| 255 | 294 | 
| 256 void ClearKeyCdm::ResetDecoder(cdm::StreamType) { | 295 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { | 
| 257   NOTIMPLEMENTED(); | 296 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 
|  | 297   DCHECK(decoder_type == cdm::kStreamTypeVideo); | 
|  | 298   video_decoder_->Reset(); | 
|  | 299 #endif | 
| 258 } | 300 } | 
| 259 | 301 | 
| 260 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType) { | 302 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { | 
| 261   NOTIMPLEMENTED(); | 303 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 
|  | 304   DCHECK(decoder_type == cdm::kStreamTypeVideo); | 
|  | 305   video_decoder_->Deinitialize(); | 
|  | 306 #endif | 
| 262 } | 307 } | 
| 263 | 308 | 
| 264 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( | 309 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( | 
| 265     const cdm::InputBuffer& encrypted_buffer, | 310     const cdm::InputBuffer& encrypted_buffer, | 
| 266     cdm::VideoFrame* video_frame) { | 311     cdm::VideoFrame* decoded_frame) { | 
| 267   if (!encrypted_buffer.data) { | 312   if (!encrypted_buffer.data) { | 
| 268     video_frame->set_format(cdm::kEmptyVideoFrame); | 313     decoded_frame->set_format(cdm::kEmptyVideoFrame); | 
| 269     return cdm::kSuccess; | 314     return cdm::kSuccess; | 
| 270   } | 315   } | 
| 271 | 316 | 
| 272   scoped_refptr<media::DecoderBuffer> decoder_buffer = | 317   scoped_refptr<media::DecoderBuffer> decoder_buffer = | 
| 273       CopyDecoderBufferFrom(encrypted_buffer); | 318       CopyDecoderBufferFrom(encrypted_buffer); | 
| 274 | 319 | 
| 275   // Callback is called synchronously, so we can use variables on the stack. | 320   // Callback is called synchronously, so we can use variables on the stack. | 
| 276   media::Decryptor::Status status; | 321   media::Decryptor::Status status; | 
| 277   scoped_refptr<media::DecoderBuffer> buffer; | 322   scoped_refptr<media::DecoderBuffer> buffer; | 
| 278   decryptor_.Decrypt(media::Decryptor::kVideo, | 323   decryptor_.Decrypt(media::Decryptor::kVideo, | 
| 279                      decoder_buffer, | 324                      decoder_buffer, | 
| 280                      base::Bind(&CopyDecryptResults, &status, &buffer)); | 325                      base::Bind(&CopyDecryptResults, &status, &buffer)); | 
| 281 | 326 | 
| 282   if (status == media::Decryptor::kError) | 327   if (status == media::Decryptor::kError) | 
| 283     return cdm::kDecryptError; | 328     return cdm::kDecryptError; | 
| 284 | 329 | 
| 285   if (status == media::Decryptor::kNoKey) | 330   if (status == media::Decryptor::kNoKey) | 
| 286     return cdm::kNoKey; | 331     return cdm::kNoKey; | 
| 287 | 332 | 
| 288 #if !defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | 333 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 
|  | 334   DCHECK(status == media::Decryptor::kSuccess); | 
|  | 335   DCHECK(buffer); | 
|  | 336   return video_decoder_->DecodeFrame(buffer.get()->GetData(), | 
|  | 337                                      buffer->GetDataSize(), | 
|  | 338                                      encrypted_buffer.timestamp, | 
|  | 339                                      decoded_frame); | 
|  | 340 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | 
|  | 341   GenerateFakeVideoFrame(decoder_buffer->GetTimestamp(), decoded_frame); | 
|  | 342   return cdm::kSuccess; | 
|  | 343 #else | 
| 289   NOTIMPLEMENTED(); | 344   NOTIMPLEMENTED(); | 
| 290   return cdm::kDecodeError; | 345   return cdm::kDecodeError; | 
| 291 #else | 346 #endif  // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | 
| 292   GenerateFakeVideoFrame(decoder_buffer->GetTimestamp(), video_frame); |  | 
| 293   return cdm::kSuccess; |  | 
| 294 #endif  // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER |  | 
| 295 } | 347 } | 
| 296 | 348 | 
| 297 #if defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | 349 #if defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | 
| 298 void ClearKeyCdm::GenerateFakeVideoFrame(base::TimeDelta timestamp, | 350 void ClearKeyCdm::GenerateFakeVideoFrame(base::TimeDelta timestamp, | 
| 299                                          cdm::VideoFrame* video_frame) { | 351                                          cdm::VideoFrame* video_frame) { | 
| 300   // Choose non-zero alignment and padding on purpose for testing. | 352   // Choose non-zero alignment and padding on purpose for testing. | 
| 301   const int kAlignment = 8; | 353   const int kAlignment = 8; | 
| 302   const int kPadding = 16; | 354   const int kPadding = 16; | 
| 303   const int kPlanePadding = 128; | 355   const int kPlanePadding = 128; | 
| 304 | 356 | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 337 #endif  // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER | 389 #endif  // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER | 
| 338 | 390 | 
| 339 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( | 391 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( | 
| 340     const cdm::InputBuffer& encrypted_buffer, | 392     const cdm::InputBuffer& encrypted_buffer, | 
| 341     cdm::Buffer* sample_buffer) { | 393     cdm::Buffer* sample_buffer) { | 
| 342   NOTIMPLEMENTED(); | 394   NOTIMPLEMENTED(); | 
| 343   return cdm::kDecryptError; | 395   return cdm::kDecryptError; | 
| 344 } | 396 } | 
| 345 | 397 | 
| 346 }  // namespace webkit_media | 398 }  // namespace webkit_media | 
| OLD | NEW | 
|---|