| 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" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "media/base/audio_decoder_config.h" | 12 #include "media/base/audio_decoder_config.h" |
| 13 #include "media/base/video_decoder_config.h" | 13 #include "media/base/video_decoder_config.h" |
| 14 #include "media/base/bind_to_loop.h" | 14 #include "media/base/bind_to_loop.h" |
| 15 #include "media/base/decoder_buffer.h" | 15 #include "media/base/decoder_buffer.h" |
| 16 #include "media/base/decryptor.h" | 16 #include "media/base/decryptor.h" |
| 17 #include "media/base/demuxer_stream.h" | 17 #include "media/base/demuxer_stream.h" |
| 18 #include "media/base/pipeline.h" | 18 #include "media/base/pipeline.h" |
| 19 | 19 |
| 20 namespace media { | 20 namespace media { |
| 21 | 21 |
| 22 #define BIND_TO_LOOP(function) \ | 22 #define BIND_TO_LOOP(function) \ |
| 23 media::BindToLoop(message_loop_, base::Bind(function, weak_this_)) | 23 media::BindToLoop(task_runner_, base::Bind(function, weak_this_)) |
| 24 | 24 |
| 25 static bool IsStreamValidAndEncrypted(DemuxerStream* stream) { | 25 static bool IsStreamValidAndEncrypted(DemuxerStream* stream) { |
| 26 return ((stream->type() == DemuxerStream::AUDIO && | 26 return ((stream->type() == DemuxerStream::AUDIO && |
| 27 stream->audio_decoder_config().IsValidConfig() && | 27 stream->audio_decoder_config().IsValidConfig() && |
| 28 stream->audio_decoder_config().is_encrypted()) || | 28 stream->audio_decoder_config().is_encrypted()) || |
| 29 (stream->type() == DemuxerStream::VIDEO && | 29 (stream->type() == DemuxerStream::VIDEO && |
| 30 stream->video_decoder_config().IsValidConfig() && | 30 stream->video_decoder_config().IsValidConfig() && |
| 31 stream->video_decoder_config().is_encrypted())); | 31 stream->video_decoder_config().is_encrypted())); |
| 32 } | 32 } |
| 33 | 33 |
| 34 DecryptingDemuxerStream::DecryptingDemuxerStream( | 34 DecryptingDemuxerStream::DecryptingDemuxerStream( |
| 35 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 35 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 36 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 36 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
| 37 : message_loop_(message_loop), | 37 : task_runner_(task_runner), |
| 38 weak_factory_(this), | 38 weak_factory_(this), |
| 39 state_(kUninitialized), | 39 state_(kUninitialized), |
| 40 demuxer_stream_(NULL), | 40 demuxer_stream_(NULL), |
| 41 set_decryptor_ready_cb_(set_decryptor_ready_cb), | 41 set_decryptor_ready_cb_(set_decryptor_ready_cb), |
| 42 decryptor_(NULL), | 42 decryptor_(NULL), |
| 43 key_added_while_decrypt_pending_(false) { | 43 key_added_while_decrypt_pending_(false) { |
| 44 } | 44 } |
| 45 | 45 |
| 46 void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, | 46 void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, |
| 47 const PipelineStatusCB& status_cb) { | 47 const PipelineStatusCB& status_cb) { |
| 48 DVLOG(2) << __FUNCTION__; | 48 DVLOG(2) << __FUNCTION__; |
| 49 DCHECK(message_loop_->BelongsToCurrentThread()); | 49 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 50 DCHECK_EQ(state_, kUninitialized) << state_; | 50 DCHECK_EQ(state_, kUninitialized) << state_; |
| 51 | 51 |
| 52 DCHECK(!demuxer_stream_); | 52 DCHECK(!demuxer_stream_); |
| 53 weak_this_ = weak_factory_.GetWeakPtr(); | 53 weak_this_ = weak_factory_.GetWeakPtr(); |
| 54 demuxer_stream_ = stream; | 54 demuxer_stream_ = stream; |
| 55 init_cb_ = BindToCurrentLoop(status_cb); | 55 init_cb_ = BindToCurrentLoop(status_cb); |
| 56 | 56 |
| 57 InitializeDecoderConfig(); | 57 InitializeDecoderConfig(); |
| 58 | 58 |
| 59 state_ = kDecryptorRequested; | 59 state_ = kDecryptorRequested; |
| 60 set_decryptor_ready_cb_.Run( | 60 set_decryptor_ready_cb_.Run( |
| 61 BIND_TO_LOOP(&DecryptingDemuxerStream::SetDecryptor)); | 61 BIND_TO_LOOP(&DecryptingDemuxerStream::SetDecryptor)); |
| 62 } | 62 } |
| 63 | 63 |
| 64 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { | 64 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { |
| 65 DVLOG(3) << __FUNCTION__; | 65 DVLOG(3) << __FUNCTION__; |
| 66 DCHECK(message_loop_->BelongsToCurrentThread()); | 66 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 67 DCHECK_EQ(state_, kIdle) << state_; | 67 DCHECK_EQ(state_, kIdle) << state_; |
| 68 DCHECK(!read_cb.is_null()); | 68 DCHECK(!read_cb.is_null()); |
| 69 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported."; | 69 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported."; |
| 70 | 70 |
| 71 read_cb_ = BindToCurrentLoop(read_cb); | 71 read_cb_ = BindToCurrentLoop(read_cb); |
| 72 state_ = kPendingDemuxerRead; | 72 state_ = kPendingDemuxerRead; |
| 73 demuxer_stream_->Read( | 73 demuxer_stream_->Read( |
| 74 base::Bind(&DecryptingDemuxerStream::DecryptBuffer, weak_this_)); | 74 base::Bind(&DecryptingDemuxerStream::DecryptBuffer, weak_this_)); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void DecryptingDemuxerStream::Reset(const base::Closure& closure) { | 77 void DecryptingDemuxerStream::Reset(const base::Closure& closure) { |
| 78 DVLOG(2) << __FUNCTION__ << " - state: " << state_; | 78 DVLOG(2) << __FUNCTION__ << " - state: " << state_; |
| 79 DCHECK(message_loop_->BelongsToCurrentThread()); | 79 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 80 DCHECK(state_ != kUninitialized) << state_; | 80 DCHECK(state_ != kUninitialized) << state_; |
| 81 DCHECK(reset_cb_.is_null()); | 81 DCHECK(reset_cb_.is_null()); |
| 82 | 82 |
| 83 reset_cb_ = BindToCurrentLoop(closure); | 83 reset_cb_ = BindToCurrentLoop(closure); |
| 84 | 84 |
| 85 if (state_ == kDecryptorRequested) { | 85 if (state_ == kDecryptorRequested) { |
| 86 DCHECK(!init_cb_.is_null()); | 86 DCHECK(!init_cb_.is_null()); |
| 87 set_decryptor_ready_cb_.Run(DecryptorReadyCB()); | 87 set_decryptor_ready_cb_.Run(DecryptorReadyCB()); |
| 88 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | 88 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
| 89 DoReset(); | 89 DoReset(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 void DecryptingDemuxerStream::EnableBitstreamConverter() { | 131 void DecryptingDemuxerStream::EnableBitstreamConverter() { |
| 132 demuxer_stream_->EnableBitstreamConverter(); | 132 demuxer_stream_->EnableBitstreamConverter(); |
| 133 } | 133 } |
| 134 | 134 |
| 135 DecryptingDemuxerStream::~DecryptingDemuxerStream() { | 135 DecryptingDemuxerStream::~DecryptingDemuxerStream() { |
| 136 DVLOG(2) << __FUNCTION__ << " : state_ = " << state_; | 136 DVLOG(2) << __FUNCTION__ << " : state_ = " << state_; |
| 137 } | 137 } |
| 138 | 138 |
| 139 void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) { | 139 void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) { |
| 140 DVLOG(2) << __FUNCTION__; | 140 DVLOG(2) << __FUNCTION__; |
| 141 DCHECK(message_loop_->BelongsToCurrentThread()); | 141 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 142 DCHECK_EQ(state_, kDecryptorRequested) << state_; | 142 DCHECK_EQ(state_, kDecryptorRequested) << state_; |
| 143 DCHECK(!init_cb_.is_null()); | 143 DCHECK(!init_cb_.is_null()); |
| 144 DCHECK(!set_decryptor_ready_cb_.is_null()); | 144 DCHECK(!set_decryptor_ready_cb_.is_null()); |
| 145 | 145 |
| 146 set_decryptor_ready_cb_.Reset(); | 146 set_decryptor_ready_cb_.Reset(); |
| 147 | 147 |
| 148 if (!decryptor) { | 148 if (!decryptor) { |
| 149 state_ = kUninitialized; | 149 state_ = kUninitialized; |
| 150 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 150 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 151 return; | 151 return; |
| 152 } | 152 } |
| 153 | 153 |
| 154 decryptor_ = decryptor; | 154 decryptor_ = decryptor; |
| 155 | 155 |
| 156 decryptor_->RegisterNewKeyCB( | 156 decryptor_->RegisterNewKeyCB( |
| 157 GetDecryptorStreamType(), | 157 GetDecryptorStreamType(), |
| 158 BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded)); | 158 BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded)); |
| 159 | 159 |
| 160 state_ = kIdle; | 160 state_ = kIdle; |
| 161 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 161 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 162 } | 162 } |
| 163 | 163 |
| 164 void DecryptingDemuxerStream::DecryptBuffer( | 164 void DecryptingDemuxerStream::DecryptBuffer( |
| 165 DemuxerStream::Status status, | 165 DemuxerStream::Status status, |
| 166 const scoped_refptr<DecoderBuffer>& buffer) { | 166 const scoped_refptr<DecoderBuffer>& buffer) { |
| 167 DVLOG(3) << __FUNCTION__; | 167 DVLOG(3) << __FUNCTION__; |
| 168 DCHECK(message_loop_->BelongsToCurrentThread()); | 168 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 169 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; | 169 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; |
| 170 DCHECK(!read_cb_.is_null()); | 170 DCHECK(!read_cb_.is_null()); |
| 171 DCHECK_EQ(buffer.get() != NULL, status == kOk) << status; | 171 DCHECK_EQ(buffer.get() != NULL, status == kOk) << status; |
| 172 | 172 |
| 173 // Even when |!reset_cb_.is_null()|, we need to pass |kConfigChanged| back to | 173 // Even when |!reset_cb_.is_null()|, we need to pass |kConfigChanged| back to |
| 174 // the caller so that the downstream decoder can be properly reinitialized. | 174 // the caller so that the downstream decoder can be properly reinitialized. |
| 175 if (status == kConfigChanged) { | 175 if (status == kConfigChanged) { |
| 176 DVLOG(2) << "DoDecryptBuffer() - kConfigChanged."; | 176 DVLOG(2) << "DoDecryptBuffer() - kConfigChanged."; |
| 177 DCHECK_EQ(demuxer_stream_->type() == AUDIO, audio_config_.IsValidConfig()); | 177 DCHECK_EQ(demuxer_stream_->type() == AUDIO, audio_config_.IsValidConfig()); |
| 178 DCHECK_EQ(demuxer_stream_->type() == VIDEO, video_config_.IsValidConfig()); | 178 DCHECK_EQ(demuxer_stream_->type() == VIDEO, video_config_.IsValidConfig()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 base::ResetAndReturn(&read_cb_).Run(kOk, decrypted); | 220 base::ResetAndReturn(&read_cb_).Run(kOk, decrypted); |
| 221 return; | 221 return; |
| 222 } | 222 } |
| 223 | 223 |
| 224 pending_buffer_to_decrypt_ = buffer; | 224 pending_buffer_to_decrypt_ = buffer; |
| 225 state_ = kPendingDecrypt; | 225 state_ = kPendingDecrypt; |
| 226 DecryptPendingBuffer(); | 226 DecryptPendingBuffer(); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void DecryptingDemuxerStream::DecryptPendingBuffer() { | 229 void DecryptingDemuxerStream::DecryptPendingBuffer() { |
| 230 DCHECK(message_loop_->BelongsToCurrentThread()); | 230 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 231 DCHECK_EQ(state_, kPendingDecrypt) << state_; | 231 DCHECK_EQ(state_, kPendingDecrypt) << state_; |
| 232 decryptor_->Decrypt( | 232 decryptor_->Decrypt( |
| 233 GetDecryptorStreamType(), | 233 GetDecryptorStreamType(), |
| 234 pending_buffer_to_decrypt_, | 234 pending_buffer_to_decrypt_, |
| 235 BIND_TO_LOOP(&DecryptingDemuxerStream::DeliverBuffer)); | 235 BIND_TO_LOOP(&DecryptingDemuxerStream::DeliverBuffer)); |
| 236 } | 236 } |
| 237 | 237 |
| 238 void DecryptingDemuxerStream::DeliverBuffer( | 238 void DecryptingDemuxerStream::DeliverBuffer( |
| 239 Decryptor::Status status, | 239 Decryptor::Status status, |
| 240 const scoped_refptr<DecoderBuffer>& decrypted_buffer) { | 240 const scoped_refptr<DecoderBuffer>& decrypted_buffer) { |
| 241 DVLOG(3) << __FUNCTION__ << " - status: " << status; | 241 DVLOG(3) << __FUNCTION__ << " - status: " << status; |
| 242 DCHECK(message_loop_->BelongsToCurrentThread()); | 242 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 243 DCHECK_EQ(state_, kPendingDecrypt) << state_; | 243 DCHECK_EQ(state_, kPendingDecrypt) << state_; |
| 244 DCHECK_NE(status, Decryptor::kNeedMoreData); | 244 DCHECK_NE(status, Decryptor::kNeedMoreData); |
| 245 DCHECK(!read_cb_.is_null()); | 245 DCHECK(!read_cb_.is_null()); |
| 246 DCHECK(pending_buffer_to_decrypt_.get()); | 246 DCHECK(pending_buffer_to_decrypt_.get()); |
| 247 | 247 |
| 248 bool need_to_try_again_if_nokey = key_added_while_decrypt_pending_; | 248 bool need_to_try_again_if_nokey = key_added_while_decrypt_pending_; |
| 249 key_added_while_decrypt_pending_ = false; | 249 key_added_while_decrypt_pending_ = false; |
| 250 | 250 |
| 251 if (!reset_cb_.is_null()) { | 251 if (!reset_cb_.is_null()) { |
| 252 pending_buffer_to_decrypt_ = NULL; | 252 pending_buffer_to_decrypt_ = NULL; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 277 return; | 277 return; |
| 278 } | 278 } |
| 279 | 279 |
| 280 DCHECK_EQ(status, Decryptor::kSuccess); | 280 DCHECK_EQ(status, Decryptor::kSuccess); |
| 281 pending_buffer_to_decrypt_ = NULL; | 281 pending_buffer_to_decrypt_ = NULL; |
| 282 state_ = kIdle; | 282 state_ = kIdle; |
| 283 base::ResetAndReturn(&read_cb_).Run(kOk, decrypted_buffer); | 283 base::ResetAndReturn(&read_cb_).Run(kOk, decrypted_buffer); |
| 284 } | 284 } |
| 285 | 285 |
| 286 void DecryptingDemuxerStream::OnKeyAdded() { | 286 void DecryptingDemuxerStream::OnKeyAdded() { |
| 287 DCHECK(message_loop_->BelongsToCurrentThread()); | 287 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 288 | 288 |
| 289 if (state_ == kPendingDecrypt) { | 289 if (state_ == kPendingDecrypt) { |
| 290 key_added_while_decrypt_pending_ = true; | 290 key_added_while_decrypt_pending_ = true; |
| 291 return; | 291 return; |
| 292 } | 292 } |
| 293 | 293 |
| 294 if (state_ == kWaitingForKey) { | 294 if (state_ == kWaitingForKey) { |
| 295 state_ = kPendingDecrypt; | 295 state_ = kPendingDecrypt; |
| 296 DecryptPendingBuffer(); | 296 DecryptPendingBuffer(); |
| 297 } | 297 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 break; | 356 break; |
| 357 } | 357 } |
| 358 | 358 |
| 359 default: | 359 default: |
| 360 NOTREACHED(); | 360 NOTREACHED(); |
| 361 return; | 361 return; |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 | 364 |
| 365 } // namespace media | 365 } // namespace media |
| OLD | NEW |