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

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: Add TODO. 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
47 // TODO(tomfinegan): Add and implement cdm::InitializeCdmModule(),
48 // and call |av_register_all()| from there.
49 av_register_all();
50
37 return true; 51 return true;
38 } 52 }
39 53
40 static bool g_cdm_module_initialized = InitializeFFmpegLibraries(); 54 static bool g_cdm_module_initialized = InitializeFFmpegLibraries();
41 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER 55 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
42 56
43 static const char kClearKeyCdmVersion[] = "0.1.0.0"; 57 static const char kClearKeyCdmVersion[] = "0.1.0.0";
44 58
45 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is 59 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is
46 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. 60 // 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()), 276 memcpy(reinterpret_cast<void*>(decrypted_block->buffer()->data()),
263 buffer->GetData(), 277 buffer->GetData(),
264 buffer->GetDataSize()); 278 buffer->GetDataSize());
265 decrypted_block->set_timestamp(buffer->GetTimestamp().InMicroseconds()); 279 decrypted_block->set_timestamp(buffer->GetTimestamp().InMicroseconds());
266 280
267 return cdm::kSuccess; 281 return cdm::kSuccess;
268 } 282 }
269 283
270 cdm::Status ClearKeyCdm::InitializeAudioDecoder( 284 cdm::Status ClearKeyCdm::InitializeAudioDecoder(
271 const cdm::AudioDecoderConfig& audio_decoder_config) { 285 const cdm::AudioDecoderConfig& audio_decoder_config) {
272 #if !defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 286 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
273 NOTIMPLEMENTED(); 287 if (!audio_decoder_)
274 return cdm::kSessionError; 288 audio_decoder_.reset(new webkit_media::FFmpegCdmAudioDecoder(allocator_));
275 #else 289
290 if (!audio_decoder_->Initialize(audio_decoder_config))
291 return cdm::kSessionError;
292
293 return cdm::kSuccess;
294 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
276 channel_count_ = audio_decoder_config.channel_count; 295 channel_count_ = audio_decoder_config.channel_count;
277 bits_per_channel_ = audio_decoder_config.bits_per_channel; 296 bits_per_channel_ = audio_decoder_config.bits_per_channel;
278 samples_per_second_ = audio_decoder_config.samples_per_second; 297 samples_per_second_ = audio_decoder_config.samples_per_second;
279 return cdm::kSuccess; 298 return cdm::kSuccess;
280 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 299 #else
300 NOTIMPLEMENTED();
301 return cdm::kSessionError;
302 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
281 } 303 }
282 304
283 cdm::Status ClearKeyCdm::InitializeVideoDecoder( 305 cdm::Status ClearKeyCdm::InitializeVideoDecoder(
284 const cdm::VideoDecoderConfig& video_decoder_config) { 306 const cdm::VideoDecoderConfig& video_decoder_config) {
285 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) 307 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
286 if (!video_decoder_) 308 if (!video_decoder_)
287 video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_)); 309 video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_));
288 310
289 if (!video_decoder_->Initialize(video_decoder_config)) 311 if (!video_decoder_->Initialize(video_decoder_config))
290 return cdm::kSessionError; 312 return cdm::kSessionError;
291 313
292 return cdm::kSuccess; 314 return cdm::kSuccess;
293 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) 315 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER)
294 video_size_ = video_decoder_config.coded_size; 316 video_size_ = video_decoder_config.coded_size;
295 return cdm::kSuccess; 317 return cdm::kSuccess;
296 #else 318 #else
297 NOTIMPLEMENTED(); 319 NOTIMPLEMENTED();
298 return cdm::kSessionError; 320 return cdm::kSessionError;
299 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER 321 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
300 } 322 }
301 323
302 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { 324 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) {
303 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 325 DVLOG(1) << "ResetDecoder()";
326 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
327 switch (decoder_type) {
328 case cdm::kStreamTypeVideo:
329 video_decoder_->Reset();
330 break;
331 case cdm::kStreamTypeAudio:
332 audio_decoder_->Reset();
333 break;
334 default:
335 NOTREACHED() << "ResetDecoder(): invalid cdm::StreamType";
336 }
337 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
304 if (decoder_type == cdm::kStreamTypeAudio) { 338 if (decoder_type == cdm::kStreamTypeAudio) {
305 last_timestamp_ = media::kNoTimestamp(); 339 last_timestamp_ = media::kNoTimestamp();
306 last_duration_ = media::kInfiniteDuration(); 340 last_duration_ = media::kInfiniteDuration();
307 } 341 }
308 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 342 #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 } 343 }
315 344
316 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { 345 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) {
317 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 346 DVLOG(1) << "DeinitializeDecoder()";
347 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
348 switch (decoder_type) {
349 case cdm::kStreamTypeVideo:
350 video_decoder_->Deinitialize();
351 break;
352 case cdm::kStreamTypeAudio:
353 audio_decoder_->Deinitialize();
354 break;
355 default:
356 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType";
357 }
358 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
318 if (decoder_type == cdm::kStreamTypeAudio) { 359 if (decoder_type == cdm::kStreamTypeAudio) {
319 last_timestamp_ = media::kNoTimestamp(); 360 last_timestamp_ = media::kNoTimestamp();
320 last_duration_ = media::kInfiniteDuration(); 361 last_duration_ = media::kInfiniteDuration();
321 } 362 }
322 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 363 #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 } 364 }
329 365
330 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( 366 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame(
331 const cdm::InputBuffer& encrypted_buffer, 367 const cdm::InputBuffer& encrypted_buffer,
332 cdm::VideoFrame* decoded_frame) { 368 cdm::VideoFrame* decoded_frame) {
333 DVLOG(1) << "DecryptAndDecodeFrame()"; 369 DVLOG(1) << "DecryptAndDecodeFrame()";
334 370
335 scoped_refptr<media::DecoderBuffer> buffer; 371 scoped_refptr<media::DecoderBuffer> buffer;
336 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); 372 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer);
337 373
(...skipping 25 matching lines...) Expand all
363 const cdm::InputBuffer& encrypted_buffer, 399 const cdm::InputBuffer& encrypted_buffer,
364 cdm::AudioFrames* audio_frames) { 400 cdm::AudioFrames* audio_frames) {
365 DVLOG(1) << "DecryptAndDecodeSamples()"; 401 DVLOG(1) << "DecryptAndDecodeSamples()";
366 402
367 scoped_refptr<media::DecoderBuffer> buffer; 403 scoped_refptr<media::DecoderBuffer> buffer;
368 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); 404 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer);
369 405
370 if (status != cdm::kSuccess) 406 if (status != cdm::kSuccess)
371 return status; 407 return status;
372 408
373 #if !defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 409 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
374 NOTIMPLEMENTED(); 410 DCHECK(status == cdm::kSuccess);
375 return cdm::kDecodeError; 411 DCHECK(buffer);
376 #else 412 return audio_decoder_->DecodeBuffer(buffer.get()->GetData(),
413 buffer->GetDataSize(),
414 encrypted_buffer.timestamp,
415 audio_frames);
416 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
377 if (buffer->IsEndOfStream()) { 417 if (buffer->IsEndOfStream()) {
378 // Upon the first EOS frame, return a frame with |last_duration_|. 418 // Upon the first EOS frame, return a frame with |last_duration_|.
379 if (last_duration_ != media::kInfiniteDuration()) { 419 if (last_duration_ != media::kInfiniteDuration()) {
380 DCHECK(last_timestamp_ != media::kNoTimestamp()); 420 DCHECK(last_timestamp_ != media::kNoTimestamp());
381 GenerateFakeAudioFrames(audio_frames); 421 GenerateFakeAudioFrames(audio_frames);
382 last_timestamp_ = media::kNoTimestamp(); 422 last_timestamp_ = media::kNoTimestamp();
383 last_duration_ = media::kInfiniteDuration(); 423 last_duration_ = media::kInfiniteDuration();
384 return cdm::kSuccess; 424 return cdm::kSuccess;
385 } 425 }
386 426
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 537
498 static unsigned char color = 0; 538 static unsigned char color = 0;
499 color += 10; 539 color += 10;
500 540
501 memset(reinterpret_cast<void*>(video_frame->frame_buffer()->data()), 541 memset(reinterpret_cast<void*>(video_frame->frame_buffer()->data()),
502 color, frame_size); 542 color, frame_size);
503 } 543 }
504 #endif // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER 544 #endif // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER
505 545
506 } // namespace webkit_media 546 } // namespace webkit_media
OLDNEW
« no previous file with comments | « webkit/media/crypto/ppapi/clear_key_cdm.h ('k') | webkit/media/crypto/ppapi/ffmpeg_cdm_audio_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698