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