Commit 94f07b52 authored by xhwang@chromium.org's avatar xhwang@chromium.org

Add TrackableCallback in ContentDecryptorDelegate.

The TrackableCallback manages the callback and the request ID so that we don't
need to manage them separately.

Also in this CL:
- Using media::Decryptor in .cc file.
- Renaming: pending_foo_cb_ -> foo_cb_

Review URL: https://codereview.chromium.org/105743010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243460 0039d316-1c4b-4281-b951-d872f2087c98
parent 14a6131c
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "ppapi/thunk/ppb_buffer_api.h" #include "ppapi/thunk/ppb_buffer_api.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
using media::Decryptor;
using ppapi::ArrayBufferVar; using ppapi::ArrayBufferVar;
using ppapi::PpapiGlobals; using ppapi::PpapiGlobals;
using ppapi::ScopedPPResource; using ppapi::ScopedPPResource;
...@@ -186,31 +187,31 @@ PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat( ...@@ -186,31 +187,31 @@ PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat(
} }
} }
media::Decryptor::Status PpDecryptResultToMediaDecryptorStatus( Decryptor::Status PpDecryptResultToMediaDecryptorStatus(
PP_DecryptResult result) { PP_DecryptResult result) {
switch (result) { switch (result) {
case PP_DECRYPTRESULT_SUCCESS: case PP_DECRYPTRESULT_SUCCESS:
return media::Decryptor::kSuccess; return Decryptor::kSuccess;
case PP_DECRYPTRESULT_DECRYPT_NOKEY: case PP_DECRYPTRESULT_DECRYPT_NOKEY:
return media::Decryptor::kNoKey; return Decryptor::kNoKey;
case PP_DECRYPTRESULT_NEEDMOREDATA: case PP_DECRYPTRESULT_NEEDMOREDATA:
return media::Decryptor::kNeedMoreData; return Decryptor::kNeedMoreData;
case PP_DECRYPTRESULT_DECRYPT_ERROR: case PP_DECRYPTRESULT_DECRYPT_ERROR:
return media::Decryptor::kError; return Decryptor::kError;
case PP_DECRYPTRESULT_DECODE_ERROR: case PP_DECRYPTRESULT_DECODE_ERROR:
return media::Decryptor::kError; return Decryptor::kError;
default: default:
NOTREACHED(); NOTREACHED();
return media::Decryptor::kError; return Decryptor::kError;
} }
} }
PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType( PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType(
media::Decryptor::StreamType stream_type) { Decryptor::StreamType stream_type) {
switch (stream_type) { switch (stream_type) {
case media::Decryptor::kAudio: case Decryptor::kAudio:
return PP_DECRYPTORSTREAMTYPE_AUDIO; return PP_DECRYPTORSTREAMTYPE_AUDIO;
case media::Decryptor::kVideo: case Decryptor::kVideo:
return PP_DECRYPTORSTREAMTYPE_VIDEO; return PP_DECRYPTORSTREAMTYPE_VIDEO;
default: default:
NOTREACHED(); NOTREACHED();
...@@ -247,12 +248,6 @@ ContentDecryptorDelegate::ContentDecryptorDelegate( ...@@ -247,12 +248,6 @@ ContentDecryptorDelegate::ContentDecryptorDelegate(
: pp_instance_(pp_instance), : pp_instance_(pp_instance),
plugin_decryption_interface_(plugin_decryption_interface), plugin_decryption_interface_(plugin_decryption_interface),
next_decryption_request_id_(1), next_decryption_request_id_(1),
pending_audio_decrypt_request_id_(0),
pending_video_decrypt_request_id_(0),
pending_audio_decoder_init_request_id_(0),
pending_video_decoder_init_request_id_(0),
pending_audio_decode_request_id_(0),
pending_video_decode_request_id_(0),
audio_samples_per_second_(0), audio_samples_per_second_(0),
audio_channel_count_(0), audio_channel_count_(0),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
...@@ -319,9 +314,9 @@ bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { ...@@ -319,9 +314,9 @@ bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) {
// TODO(xhwang): Remove duplication of code in Decrypt(), // TODO(xhwang): Remove duplication of code in Decrypt(),
// DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). // DecryptAndDecodeAudio() and DecryptAndDecodeVideo().
bool ContentDecryptorDelegate::Decrypt( bool ContentDecryptorDelegate::Decrypt(
media::Decryptor::StreamType stream_type, Decryptor::StreamType stream_type,
const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
const media::Decryptor::DecryptCB& decrypt_cb) { const Decryptor::DecryptCB& decrypt_cb) {
DVLOG(3) << "Decrypt() - stream_type: " << stream_type; DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
// |{audio|video}_input_resource_| is not being used by the plugin // |{audio|video}_input_resource_| is not being used by the plugin
// now because there is only one pending audio/video decrypt request at any // now because there is only one pending audio/video decrypt request at any
...@@ -346,17 +341,11 @@ bool ContentDecryptorDelegate::Decrypt( ...@@ -346,17 +341,11 @@ bool ContentDecryptorDelegate::Decrypt(
// There is only one pending decrypt request at any time per stream. This is // There is only one pending decrypt request at any time per stream. This is
// enforced by the media pipeline. // enforced by the media pipeline.
switch (stream_type) { switch (stream_type) {
case media::Decryptor::kAudio: case Decryptor::kAudio:
DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); audio_decrypt_cb_.Set(request_id, decrypt_cb);
DCHECK(pending_audio_decrypt_cb_.is_null());
pending_audio_decrypt_request_id_ = request_id;
pending_audio_decrypt_cb_ = decrypt_cb;
break; break;
case media::Decryptor::kVideo: case Decryptor::kVideo:
DCHECK_EQ(pending_video_decrypt_request_id_, 0u); video_decrypt_cb_.Set(request_id, decrypt_cb);
DCHECK(pending_video_decrypt_cb_.is_null());
pending_video_decrypt_request_id_ = request_id;
pending_video_decrypt_cb_ = decrypt_cb;
break; break;
default: default:
NOTREACHED(); NOTREACHED();
...@@ -372,26 +361,24 @@ bool ContentDecryptorDelegate::Decrypt( ...@@ -372,26 +361,24 @@ bool ContentDecryptorDelegate::Decrypt(
} }
bool ContentDecryptorDelegate::CancelDecrypt( bool ContentDecryptorDelegate::CancelDecrypt(
media::Decryptor::StreamType stream_type) { Decryptor::StreamType stream_type) {
DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type;
media::Decryptor::DecryptCB decrypt_cb; Decryptor::DecryptCB decrypt_cb;
switch (stream_type) { switch (stream_type) {
case media::Decryptor::kAudio: case Decryptor::kAudio:
// Release the shared memory as it can still be in use by the plugin. // Release the shared memory as it can still be in use by the plugin.
// The next Decrypt() call will need to allocate a new shared memory // The next Decrypt() call will need to allocate a new shared memory
// buffer. // buffer.
audio_input_resource_ = NULL; audio_input_resource_ = NULL;
pending_audio_decrypt_request_id_ = 0; decrypt_cb = audio_decrypt_cb_.ResetAndReturn();
decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_);
break; break;
case media::Decryptor::kVideo: case Decryptor::kVideo:
// Release the shared memory as it can still be in use by the plugin. // Release the shared memory as it can still be in use by the plugin.
// The next Decrypt() call will need to allocate a new shared memory // The next Decrypt() call will need to allocate a new shared memory
// buffer. // buffer.
video_input_resource_ = NULL; video_input_resource_ = NULL;
pending_video_decrypt_request_id_ = 0; decrypt_cb = video_decrypt_cb_.ResetAndReturn();
decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_);
break; break;
default: default:
NOTREACHED(); NOTREACHED();
...@@ -399,14 +386,14 @@ bool ContentDecryptorDelegate::CancelDecrypt( ...@@ -399,14 +386,14 @@ bool ContentDecryptorDelegate::CancelDecrypt(
} }
if (!decrypt_cb.is_null()) if (!decrypt_cb.is_null())
decrypt_cb.Run(media::Decryptor::kSuccess, NULL); decrypt_cb.Run(Decryptor::kSuccess, NULL);
return true; return true;
} }
bool ContentDecryptorDelegate::InitializeAudioDecoder( bool ContentDecryptorDelegate::InitializeAudioDecoder(
const media::AudioDecoderConfig& decoder_config, const media::AudioDecoderConfig& decoder_config,
const media::Decryptor::DecoderInitCB& init_cb) { const Decryptor::DecoderInitCB& init_cb) {
PP_AudioDecoderConfig pp_decoder_config; PP_AudioDecoderConfig pp_decoder_config;
pp_decoder_config.codec = pp_decoder_config.codec =
MediaAudioCodecToPpAudioCodec(decoder_config.codec()); MediaAudioCodecToPpAudioCodec(decoder_config.codec());
...@@ -428,11 +415,7 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder( ...@@ -428,11 +415,7 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder(
} }
ScopedPPResource pp_resource(extra_data_resource.get()); ScopedPPResource pp_resource(extra_data_resource.get());
DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u); audio_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb);
DCHECK(pending_audio_decoder_init_cb_.is_null());
pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id;
pending_audio_decoder_init_cb_ = init_cb;
plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_,
&pp_decoder_config, &pp_decoder_config,
pp_resource); pp_resource);
...@@ -441,7 +424,7 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder( ...@@ -441,7 +424,7 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder(
bool ContentDecryptorDelegate::InitializeVideoDecoder( bool ContentDecryptorDelegate::InitializeVideoDecoder(
const media::VideoDecoderConfig& decoder_config, const media::VideoDecoderConfig& decoder_config,
const media::Decryptor::DecoderInitCB& init_cb) { const Decryptor::DecoderInitCB& init_cb) {
PP_VideoDecoderConfig pp_decoder_config; PP_VideoDecoderConfig pp_decoder_config;
pp_decoder_config.codec = pp_decoder_config.codec =
MediaVideoCodecToPpVideoCodec(decoder_config.codec()); MediaVideoCodecToPpVideoCodec(decoder_config.codec());
...@@ -462,11 +445,7 @@ bool ContentDecryptorDelegate::InitializeVideoDecoder( ...@@ -462,11 +445,7 @@ bool ContentDecryptorDelegate::InitializeVideoDecoder(
} }
ScopedPPResource pp_resource(extra_data_resource.get()); ScopedPPResource pp_resource(extra_data_resource.get());
DCHECK_EQ(pending_video_decoder_init_request_id_, 0u); video_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb);
DCHECK(pending_video_decoder_init_cb_.is_null());
pending_video_decoder_init_request_id_ = pp_decoder_config.request_id;
pending_video_decoder_init_cb_ = init_cb;
natural_size_ = decoder_config.natural_size(); natural_size_ = decoder_config.natural_size();
plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_,
...@@ -476,7 +455,7 @@ bool ContentDecryptorDelegate::InitializeVideoDecoder( ...@@ -476,7 +455,7 @@ bool ContentDecryptorDelegate::InitializeVideoDecoder(
} }
bool ContentDecryptorDelegate::DeinitializeDecoder( bool ContentDecryptorDelegate::DeinitializeDecoder(
media::Decryptor::StreamType stream_type) { Decryptor::StreamType stream_type) {
CancelDecode(stream_type); CancelDecode(stream_type);
natural_size_ = gfx::Size(); natural_size_ = gfx::Size();
...@@ -488,8 +467,7 @@ bool ContentDecryptorDelegate::DeinitializeDecoder( ...@@ -488,8 +467,7 @@ bool ContentDecryptorDelegate::DeinitializeDecoder(
return true; return true;
} }
bool ContentDecryptorDelegate::ResetDecoder( bool ContentDecryptorDelegate::ResetDecoder(Decryptor::StreamType stream_type) {
media::Decryptor::StreamType stream_type) {
CancelDecode(stream_type); CancelDecode(stream_type);
// TODO(tomfinegan): Add decoder reset request tracking. // TODO(tomfinegan): Add decoder reset request tracking.
...@@ -500,14 +478,13 @@ bool ContentDecryptorDelegate::ResetDecoder( ...@@ -500,14 +478,13 @@ bool ContentDecryptorDelegate::ResetDecoder(
bool ContentDecryptorDelegate::DecryptAndDecodeAudio( bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
const media::Decryptor::AudioDecodeCB& audio_decode_cb) { const Decryptor::AudioDecodeCB& audio_decode_cb) {
// |audio_input_resource_| is not being used by the plugin now // |audio_input_resource_| is not being used by the plugin now
// because there is only one pending audio decode request at any time. // because there is only one pending audio decode request at any time.
// This is enforced by the media pipeline. // This is enforced by the media pipeline.
scoped_refptr<PPB_Buffer_Impl> encrypted_resource; scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
if (!MakeMediaBufferResource(media::Decryptor::kAudio, if (!MakeMediaBufferResource(
encrypted_buffer, Decryptor::kAudio, encrypted_buffer, &encrypted_resource)) {
&encrypted_resource)) {
return false; return false;
} }
...@@ -529,10 +506,7 @@ bool ContentDecryptorDelegate::DecryptAndDecodeAudio( ...@@ -529,10 +506,7 @@ bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
// enforced by the media pipeline. If this DCHECK is violated, our buffer // enforced by the media pipeline. If this DCHECK is violated, our buffer
// reuse policy is not valid, and we may have race problems for the shared // reuse policy is not valid, and we may have race problems for the shared
// buffer. // buffer.
DCHECK_EQ(pending_audio_decode_request_id_, 0u); audio_decode_cb_.Set(request_id, audio_decode_cb);
DCHECK(pending_audio_decode_cb_.is_null());
pending_audio_decode_request_id_ = request_id;
pending_audio_decode_cb_ = audio_decode_cb;
ScopedPPResource pp_resource(encrypted_resource.get()); ScopedPPResource pp_resource(encrypted_resource.get());
plugin_decryption_interface_->DecryptAndDecode(pp_instance_, plugin_decryption_interface_->DecryptAndDecode(pp_instance_,
...@@ -544,14 +518,13 @@ bool ContentDecryptorDelegate::DecryptAndDecodeAudio( ...@@ -544,14 +518,13 @@ bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
bool ContentDecryptorDelegate::DecryptAndDecodeVideo( bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
const media::Decryptor::VideoDecodeCB& video_decode_cb) { const Decryptor::VideoDecodeCB& video_decode_cb) {
// |video_input_resource_| is not being used by the plugin now // |video_input_resource_| is not being used by the plugin now
// because there is only one pending video decode request at any time. // because there is only one pending video decode request at any time.
// This is enforced by the media pipeline. // This is enforced by the media pipeline.
scoped_refptr<PPB_Buffer_Impl> encrypted_resource; scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
if (!MakeMediaBufferResource(media::Decryptor::kVideo, if (!MakeMediaBufferResource(
encrypted_buffer, Decryptor::kVideo, encrypted_buffer, &encrypted_resource)) {
&encrypted_resource)) {
return false; return false;
} }
...@@ -575,10 +548,7 @@ bool ContentDecryptorDelegate::DecryptAndDecodeVideo( ...@@ -575,10 +548,7 @@ bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
// media pipeline. If this DCHECK is violated, our buffer // media pipeline. If this DCHECK is violated, our buffer
// reuse policy is not valid, and we may have race problems for the shared // reuse policy is not valid, and we may have race problems for the shared
// buffer. // buffer.
DCHECK_EQ(pending_video_decode_request_id_, 0u); video_decode_cb_.Set(request_id, video_decode_cb);
DCHECK(pending_video_decode_cb_.is_null());
pending_video_decode_request_id_ = request_id;
pending_video_decode_cb_ = video_decode_cb;
// TODO(tomfinegan): Need to get stream type from media stack. // TODO(tomfinegan): Need to get stream type from media stack.
ScopedPPResource pp_resource(encrypted_resource.get()); ScopedPPResource pp_resource(encrypted_resource.get());
...@@ -660,26 +630,18 @@ void ContentDecryptorDelegate::DecoderInitializeDone( ...@@ -660,26 +630,18 @@ void ContentDecryptorDelegate::DecoderInitializeDone(
if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) {
// If the request ID is not valid or does not match what's saved, do // If the request ID is not valid or does not match what's saved, do
// nothing. // nothing.
if (request_id == 0 || if (request_id == 0 || !audio_decoder_init_cb_.Matches(request_id))
request_id != pending_audio_decoder_init_request_id_)
return; return;
DCHECK(!pending_audio_decoder_init_cb_.is_null()); audio_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success));
pending_audio_decoder_init_request_id_ = 0;
base::ResetAndReturn(
&pending_audio_decoder_init_cb_).Run(PP_ToBool(success));
} else { } else {
if (request_id == 0 || if (request_id == 0 || !video_decoder_init_cb_.Matches(request_id))
request_id != pending_video_decoder_init_request_id_)
return; return;
if (!success) if (!success)
natural_size_ = gfx::Size(); natural_size_ = gfx::Size();
DCHECK(!pending_video_decoder_init_cb_.is_null()); video_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success));
pending_video_decoder_init_request_id_ = 0;
base::ResetAndReturn(
&pending_video_decoder_init_cb_).Run(PP_ToBool(success));
} }
} }
...@@ -711,36 +673,32 @@ void ContentDecryptorDelegate::DeliverBlock( ...@@ -711,36 +673,32 @@ void ContentDecryptorDelegate::DeliverBlock(
return; return;
} }
media::Decryptor::DecryptCB decrypt_cb; Decryptor::DecryptCB decrypt_cb;
if (request_id == pending_audio_decrypt_request_id_) { if (audio_decrypt_cb_.Matches(request_id)) {
DCHECK(!pending_audio_decrypt_cb_.is_null()); decrypt_cb = audio_decrypt_cb_.ResetAndReturn();
pending_audio_decrypt_request_id_ = 0; } else if (video_decrypt_cb_.Matches(request_id)) {
decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); decrypt_cb = video_decrypt_cb_.ResetAndReturn();
} else if (request_id == pending_video_decrypt_request_id_) {
DCHECK(!pending_video_decrypt_cb_.is_null());
pending_video_decrypt_request_id_ = 0;
decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_);
} else { } else {
DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found";
return; return;
} }
media::Decryptor::Status status = Decryptor::Status status =
PpDecryptResultToMediaDecryptorStatus(block_info->result); PpDecryptResultToMediaDecryptorStatus(block_info->result);
if (status != media::Decryptor::kSuccess) { if (status != Decryptor::kSuccess) {
decrypt_cb.Run(status, NULL); decrypt_cb.Run(status, NULL);
return; return;
} }
EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true);
if (!enter.succeeded()) { if (!enter.succeeded()) {
decrypt_cb.Run(media::Decryptor::kError, NULL); decrypt_cb.Run(Decryptor::kError, NULL);
return; return;
} }
BufferAutoMapper mapper(enter.object()); BufferAutoMapper mapper(enter.object());
if (!mapper.data() || !mapper.size() || if (!mapper.data() || !mapper.size() ||
mapper.size() < block_info->data_size) { mapper.size() < block_info->data_size) {
decrypt_cb.Run(media::Decryptor::kError, NULL); decrypt_cb.Run(Decryptor::kError, NULL);
return; return;
} }
...@@ -751,7 +709,7 @@ void ContentDecryptorDelegate::DeliverBlock( ...@@ -751,7 +709,7 @@ void ContentDecryptorDelegate::DeliverBlock(
static_cast<uint8*>(mapper.data()), block_info->data_size)); static_cast<uint8*>(mapper.data()), block_info->data_size));
decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds(
block_info->tracking_info.timestamp)); block_info->tracking_info.timestamp));
decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer);
} }
// Use a non-class-member function here so that if for some reason // Use a non-class-member function here so that if for some reason
...@@ -796,7 +754,7 @@ void ContentDecryptorDelegate::DeliverFrame( ...@@ -796,7 +754,7 @@ void ContentDecryptorDelegate::DeliverFrame(
DVLOG(2) << "DeliverFrame() - request_id: " << request_id; DVLOG(2) << "DeliverFrame() - request_id: " << request_id;
// If the request ID is not valid or does not match what's saved, do nothing. // If the request ID is not valid or does not match what's saved, do nothing.
if (request_id == 0 || request_id != pending_video_decode_request_id_) { if (request_id == 0 || !video_decode_cb_.Matches(request_id)) {
DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found";
FreeBuffer(frame_info->tracking_info.buffer_id); FreeBuffer(frame_info->tracking_info.buffer_id);
return; return;
...@@ -805,14 +763,11 @@ void ContentDecryptorDelegate::DeliverFrame( ...@@ -805,14 +763,11 @@ void ContentDecryptorDelegate::DeliverFrame(
TRACE_EVENT_ASYNC_END0( TRACE_EVENT_ASYNC_END0(
"media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id);
DCHECK(!pending_video_decode_cb_.is_null()); Decryptor::VideoDecodeCB video_decode_cb = video_decode_cb_.ResetAndReturn();
pending_video_decode_request_id_ = 0;
media::Decryptor::VideoDecodeCB video_decode_cb =
base::ResetAndReturn(&pending_video_decode_cb_);
media::Decryptor::Status status = Decryptor::Status status =
PpDecryptResultToMediaDecryptorStatus(frame_info->result); PpDecryptResultToMediaDecryptorStatus(frame_info->result);
if (status != media::Decryptor::kSuccess) { if (status != Decryptor::kSuccess) {
DCHECK(!frame_info->tracking_info.buffer_id); DCHECK(!frame_info->tracking_info.buffer_id);
video_decode_cb.Run(status, NULL); video_decode_cb.Run(status, NULL);
return; return;
...@@ -822,7 +777,7 @@ void ContentDecryptorDelegate::DeliverFrame( ...@@ -822,7 +777,7 @@ void ContentDecryptorDelegate::DeliverFrame(
uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer);
if (!frame_data) { if (!frame_data) {
FreeBuffer(frame_info->tracking_info.buffer_id); FreeBuffer(frame_info->tracking_info.buffer_id);
video_decode_cb.Run(media::Decryptor::kError, NULL); video_decode_cb.Run(Decryptor::kError, NULL);
return; return;
} }
...@@ -851,7 +806,7 @@ void ContentDecryptorDelegate::DeliverFrame( ...@@ -851,7 +806,7 @@ void ContentDecryptorDelegate::DeliverFrame(
weak_this_, weak_this_,
frame_info->tracking_info.buffer_id)))); frame_info->tracking_info.buffer_id))));
video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); video_decode_cb.Run(Decryptor::kSuccess, decoded_frame);
} }
void ContentDecryptorDelegate::DeliverSamples( void ContentDecryptorDelegate::DeliverSamples(
...@@ -865,21 +820,18 @@ void ContentDecryptorDelegate::DeliverSamples( ...@@ -865,21 +820,18 @@ void ContentDecryptorDelegate::DeliverSamples(
DVLOG(2) << "DeliverSamples() - request_id: " << request_id; DVLOG(2) << "DeliverSamples() - request_id: " << request_id;
// If the request ID is not valid or does not match what's saved, do nothing. // If the request ID is not valid or does not match what's saved, do nothing.
if (request_id == 0 || request_id != pending_audio_decode_request_id_) { if (request_id == 0 || !audio_decode_cb_.Matches(request_id)) {
DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found";
return; return;
} }
DCHECK(!pending_audio_decode_cb_.is_null()); Decryptor::AudioDecodeCB audio_decode_cb = audio_decode_cb_.ResetAndReturn();
pending_audio_decode_request_id_ = 0;
media::Decryptor::AudioDecodeCB audio_decode_cb =
base::ResetAndReturn(&pending_audio_decode_cb_);
const media::Decryptor::AudioBuffers empty_frames; const Decryptor::AudioBuffers empty_frames;
media::Decryptor::Status status = Decryptor::Status status =
PpDecryptResultToMediaDecryptorStatus(sample_info->result); PpDecryptResultToMediaDecryptorStatus(sample_info->result);
if (status != media::Decryptor::kSuccess) { if (status != Decryptor::kSuccess) {
audio_decode_cb.Run(status, empty_frames); audio_decode_cb.Run(status, empty_frames);
return; return;
} }
...@@ -887,42 +839,38 @@ void ContentDecryptorDelegate::DeliverSamples( ...@@ -887,42 +839,38 @@ void ContentDecryptorDelegate::DeliverSamples(
media::SampleFormat sample_format = media::SampleFormat sample_format =
PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format); PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format);
media::Decryptor::AudioBuffers audio_frame_list; Decryptor::AudioBuffers audio_frame_list;
if (!DeserializeAudioFrames(audio_frames, if (!DeserializeAudioFrames(audio_frames,
sample_info->data_size, sample_info->data_size,
sample_format, sample_format,
&audio_frame_list)) { &audio_frame_list)) {
NOTREACHED() << "CDM did not serialize the buffer correctly."; NOTREACHED() << "CDM did not serialize the buffer correctly.";
audio_decode_cb.Run(media::Decryptor::kError, empty_frames); audio_decode_cb.Run(Decryptor::kError, empty_frames);
return; return;
} }
audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); audio_decode_cb.Run(Decryptor::kSuccess, audio_frame_list);
} }
// TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt().
void ContentDecryptorDelegate::CancelDecode( void ContentDecryptorDelegate::CancelDecode(Decryptor::StreamType stream_type) {
media::Decryptor::StreamType stream_type) {
switch (stream_type) { switch (stream_type) {
case media::Decryptor::kAudio: case Decryptor::kAudio:
// Release the shared memory as it can still be in use by the plugin. // Release the shared memory as it can still be in use by the plugin.
// The next DecryptAndDecode() call will need to allocate a new shared // The next DecryptAndDecode() call will need to allocate a new shared
// memory buffer. // memory buffer.
audio_input_resource_ = NULL; audio_input_resource_ = NULL;
pending_audio_decode_request_id_ = 0; if (!audio_decode_cb_.is_null())
if (!pending_audio_decode_cb_.is_null()) audio_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess,
base::ResetAndReturn(&pending_audio_decode_cb_).Run( Decryptor::AudioBuffers());
media::Decryptor::kSuccess, media::Decryptor::AudioBuffers());
break; break;
case media::Decryptor::kVideo: case Decryptor::kVideo:
// Release the shared memory as it can still be in use by the plugin. // Release the shared memory as it can still be in use by the plugin.
// The next DecryptAndDecode() call will need to allocate a new shared // The next DecryptAndDecode() call will need to allocate a new shared
// memory buffer. // memory buffer.
video_input_resource_ = NULL; video_input_resource_ = NULL;
pending_video_decode_request_id_ = 0; if (!video_decode_cb_.is_null())
if (!pending_video_decode_cb_.is_null()) video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, NULL);
base::ResetAndReturn(&pending_video_decode_cb_).Run(
media::Decryptor::kSuccess, NULL);
break; break;
default: default:
NOTREACHED(); NOTREACHED();
...@@ -930,7 +878,7 @@ void ContentDecryptorDelegate::CancelDecode( ...@@ -930,7 +878,7 @@ void ContentDecryptorDelegate::CancelDecode(
} }
bool ContentDecryptorDelegate::MakeMediaBufferResource( bool ContentDecryptorDelegate::MakeMediaBufferResource(
media::Decryptor::StreamType stream_type, Decryptor::StreamType stream_type,
const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
scoped_refptr<PPB_Buffer_Impl>* resource) { scoped_refptr<PPB_Buffer_Impl>* resource) {
TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource");
...@@ -941,11 +889,10 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource( ...@@ -941,11 +889,10 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource(
return true; return true;
} }
DCHECK(stream_type == media::Decryptor::kAudio || DCHECK(stream_type == Decryptor::kAudio || stream_type == Decryptor::kVideo);
stream_type == media::Decryptor::kVideo);
scoped_refptr<PPB_Buffer_Impl>& media_resource = scoped_refptr<PPB_Buffer_Impl>& media_resource =
(stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : (stream_type == Decryptor::kAudio) ? audio_input_resource_
video_input_resource_; : video_input_resource_;
const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size());
if (!media_resource.get() || media_resource->size() < data_size) { if (!media_resource.get() || media_resource->size() < data_size) {
...@@ -964,7 +911,7 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource( ...@@ -964,7 +911,7 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource(
media_resource_size *= 2; media_resource_size *= 2;
DVLOG(2) << "Size of media buffer for " DVLOG(2) << "Size of media buffer for "
<< ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") << ((stream_type == Decryptor::kAudio) ? "audio" : "video")
<< " stream bumped to " << media_resource_size << " stream bumped to " << media_resource_size
<< " bytes to fit input."; << " bytes to fit input.";
media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_,
...@@ -1004,7 +951,7 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames( ...@@ -1004,7 +951,7 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames(
PP_Resource audio_frames, PP_Resource audio_frames,
size_t data_size, size_t data_size,
media::SampleFormat sample_format, media::SampleFormat sample_format,
media::Decryptor::AudioBuffers* frames) { Decryptor::AudioBuffers* frames) {
DCHECK(frames); DCHECK(frames);
EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true);
if (!enter.succeeded()) if (!enter.succeeded())
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -104,6 +105,34 @@ class ContentDecryptorDelegate { ...@@ -104,6 +105,34 @@ class ContentDecryptorDelegate {
const PP_DecryptedSampleInfo* sample_info); const PP_DecryptedSampleInfo* sample_info);
private: private:
template <typename Callback>
class TrackableCallback {
public:
TrackableCallback() : id_(0u) {}
// TODO(xhwang): Check that no callback is pending in dtor.
~TrackableCallback() {};
bool Matches(uint32_t id) const { return id == id_; }
bool is_null() const { return cb_.is_null(); }
void Set(uint32_t id, const Callback& cb) {
DCHECK_EQ(id_, 0u);
DCHECK(cb_.is_null());
id_ = id;
cb_ = cb;
}
Callback ResetAndReturn() {
id_ = 0;
return base::ResetAndReturn(&cb_);
}
private:
uint32_t id_;
Callback cb_;
};
// Cancels the pending decrypt-and-decode callback for |stream_type|. // Cancels the pending decrypt-and-decode callback for |stream_type|.
void CancelDecode(media::Decryptor::StreamType stream_type); void CancelDecode(media::Decryptor::StreamType stream_type);
...@@ -154,23 +183,12 @@ class ContentDecryptorDelegate { ...@@ -154,23 +183,12 @@ class ContentDecryptorDelegate {
// of request IDs. // of request IDs.
uint32_t next_decryption_request_id_; uint32_t next_decryption_request_id_;
uint32_t pending_audio_decrypt_request_id_; TrackableCallback<media::Decryptor::DecryptCB> audio_decrypt_cb_;
media::Decryptor::DecryptCB pending_audio_decrypt_cb_; TrackableCallback<media::Decryptor::DecryptCB> video_decrypt_cb_;
TrackableCallback<media::Decryptor::DecoderInitCB> audio_decoder_init_cb_;
uint32_t pending_video_decrypt_request_id_; TrackableCallback<media::Decryptor::DecoderInitCB> video_decoder_init_cb_;
media::Decryptor::DecryptCB pending_video_decrypt_cb_; TrackableCallback<media::Decryptor::AudioDecodeCB> audio_decode_cb_;
TrackableCallback<media::Decryptor::VideoDecodeCB> video_decode_cb_;
uint32_t pending_audio_decoder_init_request_id_;
media::Decryptor::DecoderInitCB pending_audio_decoder_init_cb_;
uint32_t pending_video_decoder_init_request_id_;
media::Decryptor::DecoderInitCB pending_video_decoder_init_cb_;
uint32_t pending_audio_decode_request_id_;
media::Decryptor::AudioDecodeCB pending_audio_decode_cb_;
uint32_t pending_video_decode_request_id_;
media::Decryptor::VideoDecodeCB pending_video_decode_cb_;
// Cached audio and video input buffers. See MakeMediaBufferResource. // Cached audio and video input buffers. See MakeMediaBufferResource.
scoped_refptr<PPB_Buffer_Impl> audio_input_resource_; scoped_refptr<PPB_Buffer_Impl> audio_input_resource_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment