| 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 "media/filters/decrypting_demuxer_stream.h" | 5 #include "media/filters/decrypting_demuxer_stream.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 stream->audio_decoder_config().IsValidConfig() && | 21 stream->audio_decoder_config().IsValidConfig() && |
| 22 stream->audio_decoder_config().is_encrypted()) || | 22 stream->audio_decoder_config().is_encrypted()) || |
| 23 (stream->type() == DemuxerStream::VIDEO && | 23 (stream->type() == DemuxerStream::VIDEO && |
| 24 stream->video_decoder_config().IsValidConfig() && | 24 stream->video_decoder_config().IsValidConfig() && |
| 25 stream->video_decoder_config().is_encrypted())); | 25 stream->video_decoder_config().is_encrypted())); |
| 26 } | 26 } |
| 27 | 27 |
| 28 DecryptingDemuxerStream::DecryptingDemuxerStream( | 28 DecryptingDemuxerStream::DecryptingDemuxerStream( |
| 29 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 29 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 30 const scoped_refptr<MediaLog>& media_log, | 30 const scoped_refptr<MediaLog>& media_log, |
| 31 const SetDecryptorReadyCB& set_decryptor_ready_cb, | 31 const SetCdmReadyCB& set_cdm_ready_cb, |
| 32 const base::Closure& waiting_for_decryption_key_cb) | 32 const base::Closure& waiting_for_decryption_key_cb) |
| 33 : task_runner_(task_runner), | 33 : task_runner_(task_runner), |
| 34 media_log_(media_log), | 34 media_log_(media_log), |
| 35 state_(kUninitialized), | 35 state_(kUninitialized), |
| 36 waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), | 36 waiting_for_decryption_key_cb_(waiting_for_decryption_key_cb), |
| 37 demuxer_stream_(NULL), | 37 demuxer_stream_(NULL), |
| 38 set_decryptor_ready_cb_(set_decryptor_ready_cb), | 38 set_cdm_ready_cb_(set_cdm_ready_cb), |
| 39 decryptor_(NULL), | 39 decryptor_(NULL), |
| 40 key_added_while_decrypt_pending_(false), | 40 key_added_while_decrypt_pending_(false), |
| 41 weak_factory_(this) { | 41 weak_factory_(this) {} |
| 42 } | |
| 43 | 42 |
| 44 std::string DecryptingDemuxerStream::GetDisplayName() const { | 43 std::string DecryptingDemuxerStream::GetDisplayName() const { |
| 45 return "DecryptingDemuxerStream"; | 44 return "DecryptingDemuxerStream"; |
| 46 } | 45 } |
| 47 | 46 |
| 48 void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, | 47 void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, |
| 49 const PipelineStatusCB& status_cb) { | 48 const PipelineStatusCB& status_cb) { |
| 50 DVLOG(2) << __FUNCTION__; | 49 DVLOG(2) << __FUNCTION__; |
| 51 DCHECK(task_runner_->BelongsToCurrentThread()); | 50 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 52 DCHECK_EQ(state_, kUninitialized) << state_; | 51 DCHECK_EQ(state_, kUninitialized) << state_; |
| 53 | 52 |
| 54 DCHECK(!demuxer_stream_); | 53 DCHECK(!demuxer_stream_); |
| 55 weak_this_ = weak_factory_.GetWeakPtr(); | 54 weak_this_ = weak_factory_.GetWeakPtr(); |
| 56 demuxer_stream_ = stream; | 55 demuxer_stream_ = stream; |
| 57 init_cb_ = BindToCurrentLoop(status_cb); | 56 init_cb_ = BindToCurrentLoop(status_cb); |
| 58 | 57 |
| 59 InitializeDecoderConfig(); | 58 InitializeDecoderConfig(); |
| 60 | 59 |
| 61 state_ = kDecryptorRequested; | 60 state_ = kDecryptorRequested; |
| 62 set_decryptor_ready_cb_.Run(BindToCurrentLoop( | 61 set_cdm_ready_cb_.Run(BindToCurrentLoop( |
| 63 base::Bind(&DecryptingDemuxerStream::SetDecryptor, weak_this_))); | 62 base::Bind(&DecryptingDemuxerStream::SetCdm, weak_this_))); |
| 64 } | 63 } |
| 65 | 64 |
| 66 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { | 65 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { |
| 67 DVLOG(3) << __FUNCTION__; | 66 DVLOG(3) << __FUNCTION__; |
| 68 DCHECK(task_runner_->BelongsToCurrentThread()); | 67 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 69 DCHECK_EQ(state_, kIdle) << state_; | 68 DCHECK_EQ(state_, kIdle) << state_; |
| 70 DCHECK(!read_cb.is_null()); | 69 DCHECK(!read_cb.is_null()); |
| 71 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported."; | 70 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported."; |
| 72 | 71 |
| 73 read_cb_ = BindToCurrentLoop(read_cb); | 72 read_cb_ = BindToCurrentLoop(read_cb); |
| 74 state_ = kPendingDemuxerRead; | 73 state_ = kPendingDemuxerRead; |
| 75 demuxer_stream_->Read( | 74 demuxer_stream_->Read( |
| 76 base::Bind(&DecryptingDemuxerStream::DecryptBuffer, weak_this_)); | 75 base::Bind(&DecryptingDemuxerStream::DecryptBuffer, weak_this_)); |
| 77 } | 76 } |
| 78 | 77 |
| 79 void DecryptingDemuxerStream::Reset(const base::Closure& closure) { | 78 void DecryptingDemuxerStream::Reset(const base::Closure& closure) { |
| 80 DVLOG(2) << __FUNCTION__ << " - state: " << state_; | 79 DVLOG(2) << __FUNCTION__ << " - state: " << state_; |
| 81 DCHECK(task_runner_->BelongsToCurrentThread()); | 80 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 82 DCHECK(state_ != kUninitialized) << state_; | 81 DCHECK(state_ != kUninitialized) << state_; |
| 83 DCHECK(reset_cb_.is_null()); | 82 DCHECK(reset_cb_.is_null()); |
| 84 | 83 |
| 85 reset_cb_ = BindToCurrentLoop(closure); | 84 reset_cb_ = BindToCurrentLoop(closure); |
| 86 | 85 |
| 87 // TODO(xhwang): This should not happen. Remove it, DCHECK against the | 86 // TODO(xhwang): This should not happen. Remove it, DCHECK against the |
| 88 // condition and clean up related tests. | 87 // condition and clean up related tests. |
| 89 if (state_ == kDecryptorRequested) { | 88 if (state_ == kDecryptorRequested) { |
| 90 DCHECK(!init_cb_.is_null()); | 89 DCHECK(!init_cb_.is_null()); |
| 91 set_decryptor_ready_cb_.Run(DecryptorReadyCB()); | 90 set_cdm_ready_cb_.Run(CdmReadyCB()); |
| 92 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | 91 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
| 93 DoReset(); | 92 DoReset(); |
| 94 return; | 93 return; |
| 95 } | 94 } |
| 96 | 95 |
| 97 decryptor_->CancelDecrypt(GetDecryptorStreamType()); | 96 decryptor_->CancelDecrypt(GetDecryptorStreamType()); |
| 98 | 97 |
| 99 // Reset() cannot complete if the read callback is still pending. | 98 // Reset() cannot complete if the read callback is still pending. |
| 100 // Defer the resetting process in this case. The |reset_cb_| will be fired | 99 // Defer the resetting process in this case. The |reset_cb_| will be fired |
| 101 // after the read callback is fired - see DoDecryptBuffer() and | 100 // after the read callback is fired - see DoDecryptBuffer() and |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 DVLOG(2) << __FUNCTION__ << " : state_ = " << state_; | 152 DVLOG(2) << __FUNCTION__ << " : state_ = " << state_; |
| 154 DCHECK(task_runner_->BelongsToCurrentThread()); | 153 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 155 | 154 |
| 156 if (state_ == kUninitialized) | 155 if (state_ == kUninitialized) |
| 157 return; | 156 return; |
| 158 | 157 |
| 159 if (decryptor_) { | 158 if (decryptor_) { |
| 160 decryptor_->CancelDecrypt(GetDecryptorStreamType()); | 159 decryptor_->CancelDecrypt(GetDecryptorStreamType()); |
| 161 decryptor_ = NULL; | 160 decryptor_ = NULL; |
| 162 } | 161 } |
| 163 if (!set_decryptor_ready_cb_.is_null()) | 162 if (!set_cdm_ready_cb_.is_null()) |
| 164 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); | 163 base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); |
| 165 if (!init_cb_.is_null()) | 164 if (!init_cb_.is_null()) |
| 166 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | 165 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
| 167 if (!read_cb_.is_null()) | 166 if (!read_cb_.is_null()) |
| 168 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 167 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 169 if (!reset_cb_.is_null()) | 168 if (!reset_cb_.is_null()) |
| 170 base::ResetAndReturn(&reset_cb_).Run(); | 169 base::ResetAndReturn(&reset_cb_).Run(); |
| 171 pending_buffer_to_decrypt_ = NULL; | 170 pending_buffer_to_decrypt_ = NULL; |
| 172 } | 171 } |
| 173 | 172 |
| 174 void DecryptingDemuxerStream::SetDecryptor( | 173 void DecryptingDemuxerStream::SetCdm(CdmContext* cdm_context, |
| 175 Decryptor* decryptor, | 174 const CdmAttachedCB& cdm_attached_cb) { |
| 176 const DecryptorAttachedCB& decryptor_attached_cb) { | |
| 177 DVLOG(2) << __FUNCTION__; | 175 DVLOG(2) << __FUNCTION__; |
| 178 DCHECK(task_runner_->BelongsToCurrentThread()); | 176 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 179 DCHECK_EQ(state_, kDecryptorRequested) << state_; | 177 DCHECK_EQ(state_, kDecryptorRequested) << state_; |
| 180 DCHECK(!init_cb_.is_null()); | 178 DCHECK(!init_cb_.is_null()); |
| 181 DCHECK(!set_decryptor_ready_cb_.is_null()); | 179 DCHECK(!set_cdm_ready_cb_.is_null()); |
| 182 | 180 |
| 183 set_decryptor_ready_cb_.Reset(); | 181 set_cdm_ready_cb_.Reset(); |
| 184 | 182 |
| 185 if (!decryptor) { | 183 if (!cdm_context || !cdm_context->GetDecryptor()) { |
| 186 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": decryptor not set"; | 184 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": decryptor not set"; |
| 187 state_ = kUninitialized; | 185 state_ = kUninitialized; |
| 188 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 186 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 189 decryptor_attached_cb.Run(false); | 187 cdm_attached_cb.Run(false); |
| 190 return; | 188 return; |
| 191 } | 189 } |
| 192 | 190 |
| 193 decryptor_ = decryptor; | 191 decryptor_ = cdm_context->GetDecryptor(); |
| 194 | 192 |
| 195 decryptor_->RegisterNewKeyCB( | 193 decryptor_->RegisterNewKeyCB( |
| 196 GetDecryptorStreamType(), | 194 GetDecryptorStreamType(), |
| 197 BindToCurrentLoop( | 195 BindToCurrentLoop( |
| 198 base::Bind(&DecryptingDemuxerStream::OnKeyAdded, weak_this_))); | 196 base::Bind(&DecryptingDemuxerStream::OnKeyAdded, weak_this_))); |
| 199 | 197 |
| 200 state_ = kIdle; | 198 state_ = kIdle; |
| 201 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 199 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 202 decryptor_attached_cb.Run(true); | 200 cdm_attached_cb.Run(true); |
| 203 } | 201 } |
| 204 | 202 |
| 205 void DecryptingDemuxerStream::DecryptBuffer( | 203 void DecryptingDemuxerStream::DecryptBuffer( |
| 206 DemuxerStream::Status status, | 204 DemuxerStream::Status status, |
| 207 const scoped_refptr<DecoderBuffer>& buffer) { | 205 const scoped_refptr<DecoderBuffer>& buffer) { |
| 208 DVLOG(3) << __FUNCTION__; | 206 DVLOG(3) << __FUNCTION__; |
| 209 DCHECK(task_runner_->BelongsToCurrentThread()); | 207 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 210 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; | 208 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; |
| 211 DCHECK(!read_cb_.is_null()); | 209 DCHECK(!read_cb_.is_null()); |
| 212 DCHECK_EQ(buffer.get() != NULL, status == kOk) << status; | 210 DCHECK_EQ(buffer.get() != NULL, status == kOk) << status; |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 break; | 401 break; |
| 404 } | 402 } |
| 405 | 403 |
| 406 default: | 404 default: |
| 407 NOTREACHED(); | 405 NOTREACHED(); |
| 408 return; | 406 return; |
| 409 } | 407 } |
| 410 } | 408 } |
| 411 | 409 |
| 412 } // namespace media | 410 } // namespace media |
| OLD | NEW |