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

Side by Side Diff: webkit/media/crypto/ppapi/clear_key_cdm.cc

Issue 11260007: Add FFmpeg audio decoder for the clear key CDM. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor changes to make things work. Created 8 years, 1 month 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) 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/buffers.h" 12 #include "media/base/buffers.h"
13 #include "media/base/decoder_buffer.h" 13 #include "media/base/decoder_buffer.h"
14 14
15 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) 15 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
16 #include "base/at_exit.h" 16 #include "base/at_exit.h"
17 #include "base/file_path.h" 17 #include "base/file_path.h"
18 #include "base/path_service.h" 18 #include "base/path_service.h"
19 #include "media/base/media.h" 19 #include "media/base/media.h"
20 #include "webkit/media/crypto/ppapi/ffmpeg_cdm_audio_decoder.h"
20 #include "webkit/media/crypto/ppapi/ffmpeg_cdm_video_decoder.h" 21 #include "webkit/media/crypto/ppapi/ffmpeg_cdm_video_decoder.h"
21 22
23 // Include FFmpeg avformat.h for av_register_all().
24 extern "C" {
25 // Temporarily disable possible loss of data warning.
26 MSVC_PUSH_DISABLE_WARNING(4244);
27 #include <libavformat/avformat.h>
28 MSVC_POP_WARNING();
29 } // extern "C"
30
22 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must 31 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must
23 // exist before the call to InitializeFFmpegLibraries(). This should no longer 32 // exist before the call to InitializeFFmpegLibraries(). This should no longer
24 // be required after http://crbug.com/91970 because we'll be able to get rid of 33 // be required after http://crbug.com/91970 because we'll be able to get rid of
25 // InitializeFFmpegLibraries(). 34 // InitializeFFmpegLibraries().
26 #if !defined COMPONENT_BUILD 35 #if !defined COMPONENT_BUILD
27 static base::AtExitManager g_at_exit_manager; 36 static base::AtExitManager g_at_exit_manager;
28 #endif 37 #endif
29 38
30 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized| 39 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized|
31 // are required for running in the sandbox, and should no longer be required 40 // are required for running in the sandbox, and should no longer be required
32 // after http://crbug.com/91970 is fixed. 41 // after http://crbug.com/91970 is fixed.
33 static bool InitializeFFmpegLibraries() { 42 static bool InitializeFFmpegLibraries() {
34 FilePath file_path; 43 FilePath file_path;
35 CHECK(PathService::Get(base::DIR_EXE, &file_path)); 44 CHECK(PathService::Get(base::DIR_EXE, &file_path));
36 CHECK(media::InitializeMediaLibrary(file_path)); 45 CHECK(media::InitializeMediaLibrary(file_path));
46 av_register_all();
ddorwin 2012/10/25 01:34:17 Do you just need a single place to call this? I do
Tom Finegan 2012/10/25 04:58:37 Added TODO. Yes, the call will always be needed.
37 return true; 47 return true;
38 } 48 }
39 49
40 static bool g_cdm_module_initialized = InitializeFFmpegLibraries(); 50 static bool g_cdm_module_initialized = InitializeFFmpegLibraries();
41 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER 51 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
42 52
43 static const char kClearKeyCdmVersion[] = "0.1.0.0"; 53 static const char kClearKeyCdmVersion[] = "0.1.0.0";
44 54
45 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is 55 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is
46 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. 56 // empty, an empty (end-of-stream) media::DecoderBuffer is returned.
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 memcpy(reinterpret_cast<void*>(decrypted_block->buffer()->data()), 272 memcpy(reinterpret_cast<void*>(decrypted_block->buffer()->data()),
263 buffer->GetData(), 273 buffer->GetData(),
264 buffer->GetDataSize()); 274 buffer->GetDataSize());
265 decrypted_block->set_timestamp(buffer->GetTimestamp().InMicroseconds()); 275 decrypted_block->set_timestamp(buffer->GetTimestamp().InMicroseconds());
266 276
267 return cdm::kSuccess; 277 return cdm::kSuccess;
268 } 278 }
269 279
270 cdm::Status ClearKeyCdm::InitializeAudioDecoder( 280 cdm::Status ClearKeyCdm::InitializeAudioDecoder(
271 const cdm::AudioDecoderConfig& audio_decoder_config) { 281 const cdm::AudioDecoderConfig& audio_decoder_config) {
272 #if !defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 282 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
273 NOTIMPLEMENTED(); 283 if (!audio_decoder_)
274 return cdm::kSessionError; 284 audio_decoder_.reset(new webkit_media::FFmpegCdmAudioDecoder(allocator_));
275 #else 285
286 if (!audio_decoder_->Initialize(audio_decoder_config))
287 return cdm::kSessionError;
288
289 return cdm::kSuccess;
290 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
276 channel_count_ = audio_decoder_config.channel_count; 291 channel_count_ = audio_decoder_config.channel_count;
277 bits_per_channel_ = audio_decoder_config.bits_per_channel; 292 bits_per_channel_ = audio_decoder_config.bits_per_channel;
278 samples_per_second_ = audio_decoder_config.samples_per_second; 293 samples_per_second_ = audio_decoder_config.samples_per_second;
279 return cdm::kSuccess; 294 return cdm::kSuccess;
280 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 295 #else
296 NOTIMPLEMENTED();
297 return cdm::kSessionError;
298 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
281 } 299 }
282 300
283 cdm::Status ClearKeyCdm::InitializeVideoDecoder( 301 cdm::Status ClearKeyCdm::InitializeVideoDecoder(
284 const cdm::VideoDecoderConfig& video_decoder_config) { 302 const cdm::VideoDecoderConfig& video_decoder_config) {
285 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) 303 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
286 if (!video_decoder_) 304 if (!video_decoder_)
287 video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_)); 305 video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_));
288 306
289 if (!video_decoder_->Initialize(video_decoder_config)) 307 if (!video_decoder_->Initialize(video_decoder_config))
290 return cdm::kSessionError; 308 return cdm::kSessionError;
291 309
292 return cdm::kSuccess; 310 return cdm::kSuccess;
293 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) 311 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER)
294 video_size_ = video_decoder_config.coded_size; 312 video_size_ = video_decoder_config.coded_size;
295 return cdm::kSuccess; 313 return cdm::kSuccess;
296 #else 314 #else
297 NOTIMPLEMENTED(); 315 NOTIMPLEMENTED();
298 return cdm::kSessionError; 316 return cdm::kSessionError;
299 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER 317 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
300 } 318 }
301 319
302 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { 320 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) {
303 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 321 DVLOG(1) << "ResetDecoder()";
322 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
323 switch (decoder_type) {
324 case cdm::kStreamTypeVideo:
325 video_decoder_->Reset();
326 break;
327 case cdm::kStreamTypeAudio:
328 audio_decoder_->Reset();
329 break;
330 default:
331 NOTREACHED() << "ResetDecoder(): invalid cdm::StreamType";
332 }
333 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
304 if (decoder_type == cdm::kStreamTypeAudio) { 334 if (decoder_type == cdm::kStreamTypeAudio) {
305 last_timestamp_ = media::kNoTimestamp(); 335 last_timestamp_ = media::kNoTimestamp();
306 last_duration_ = media::kInfiniteDuration(); 336 last_duration_ = media::kInfiniteDuration();
307 } 337 }
308 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 338 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
309
310 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
311 if (decoder_type == cdm::kStreamTypeVideo)
312 video_decoder_->Reset();
313 #endif
314 } 339 }
315 340
316 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { 341 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) {
317 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 342 DVLOG(1) << "DeinitializeDecoder()";
343 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
344 switch (decoder_type) {
345 case cdm::kStreamTypeVideo:
346 video_decoder_->Deinitialize();
347 break;
348 case cdm::kStreamTypeAudio:
349 audio_decoder_->Deinitialize();
350 break;
351 default:
352 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType";
353 }
354 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
318 if (decoder_type == cdm::kStreamTypeAudio) { 355 if (decoder_type == cdm::kStreamTypeAudio) {
319 last_timestamp_ = media::kNoTimestamp(); 356 last_timestamp_ = media::kNoTimestamp();
320 last_duration_ = media::kInfiniteDuration(); 357 last_duration_ = media::kInfiniteDuration();
321 } 358 }
322 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 359 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
323
324 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
325 if (decoder_type == cdm::kStreamTypeVideo)
326 video_decoder_->Deinitialize();
327 #endif
328 } 360 }
329 361
330 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( 362 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame(
331 const cdm::InputBuffer& encrypted_buffer, 363 const cdm::InputBuffer& encrypted_buffer,
332 cdm::VideoFrame* decoded_frame) { 364 cdm::VideoFrame* decoded_frame) {
333 DVLOG(1) << "DecryptAndDecodeFrame()"; 365 DVLOG(1) << "DecryptAndDecodeFrame()";
334 366
335 scoped_refptr<media::DecoderBuffer> buffer; 367 scoped_refptr<media::DecoderBuffer> buffer;
336 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); 368 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer);
337 369
(...skipping 25 matching lines...) Expand all
363 const cdm::InputBuffer& encrypted_buffer, 395 const cdm::InputBuffer& encrypted_buffer,
364 cdm::AudioFrames* audio_frames) { 396 cdm::AudioFrames* audio_frames) {
365 DVLOG(1) << "DecryptAndDecodeSamples()"; 397 DVLOG(1) << "DecryptAndDecodeSamples()";
366 398
367 scoped_refptr<media::DecoderBuffer> buffer; 399 scoped_refptr<media::DecoderBuffer> buffer;
368 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); 400 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer);
369 401
370 if (status != cdm::kSuccess) 402 if (status != cdm::kSuccess)
371 return status; 403 return status;
372 404
373 #if !defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 405 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
374 NOTIMPLEMENTED(); 406 DCHECK(status == cdm::kSuccess);
375 return cdm::kDecodeError; 407 DCHECK(buffer);
376 #else 408 return audio_decoder_->DecodeBuffer(buffer.get()->GetData(),
409 buffer->GetDataSize(),
410 encrypted_buffer.timestamp,
411 audio_frames);
412 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
377 if (buffer->IsEndOfStream()) { 413 if (buffer->IsEndOfStream()) {
378 // Upon the first EOS frame, return a frame with |last_duration_|. 414 // Upon the first EOS frame, return a frame with |last_duration_|.
379 if (last_duration_ != media::kInfiniteDuration()) { 415 if (last_duration_ != media::kInfiniteDuration()) {
380 DCHECK(last_timestamp_ != media::kNoTimestamp()); 416 DCHECK(last_timestamp_ != media::kNoTimestamp());
381 GenerateFakeAudioFrames(audio_frames); 417 GenerateFakeAudioFrames(audio_frames);
382 last_timestamp_ = media::kNoTimestamp(); 418 last_timestamp_ = media::kNoTimestamp();
383 last_duration_ = media::kInfiniteDuration(); 419 last_duration_ = media::kInfiniteDuration();
384 return cdm::kSuccess; 420 return cdm::kSuccess;
385 } 421 }
386 422
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 533
498 static unsigned char color = 0; 534 static unsigned char color = 0;
499 color += 10; 535 color += 10;
500 536
501 memset(reinterpret_cast<void*>(video_frame->frame_buffer()->data()), 537 memset(reinterpret_cast<void*>(video_frame->frame_buffer()->data()),
502 color, frame_size); 538 color, frame_size);
503 } 539 }
504 #endif // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER 540 #endif // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER
505 541
506 } // namespace webkit_media 542 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698