Chromium Code Reviews| 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 19 matching lines...) Expand all Loading... | |
| 30 (stream->type() == DemuxerStream::VIDEO && | 30 (stream->type() == DemuxerStream::VIDEO && |
| 31 stream->video_decoder_config().IsValidConfig() && | 31 stream->video_decoder_config().IsValidConfig() && |
| 32 stream->video_decoder_config().is_encrypted())); | 32 stream->video_decoder_config().is_encrypted())); |
| 33 } | 33 } |
| 34 | 34 |
| 35 DecryptingDemuxerStream::DecryptingDemuxerStream( | 35 DecryptingDemuxerStream::DecryptingDemuxerStream( |
| 36 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 36 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| 37 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 37 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
| 38 : message_loop_(message_loop), | 38 : message_loop_(message_loop), |
| 39 state_(kUninitialized), | 39 state_(kUninitialized), |
| 40 stream_type_(UNKNOWN), | |
| 41 set_decryptor_ready_cb_(set_decryptor_ready_cb), | 40 set_decryptor_ready_cb_(set_decryptor_ready_cb), |
| 42 decryptor_(NULL), | 41 decryptor_(NULL), |
| 43 key_added_while_decrypt_pending_(false) { | 42 key_added_while_decrypt_pending_(false) { |
| 44 } | 43 } |
| 45 | 44 |
| 46 void DecryptingDemuxerStream::Initialize( | 45 void DecryptingDemuxerStream::Initialize( |
| 47 const scoped_refptr<DemuxerStream>& stream, | 46 const scoped_refptr<DemuxerStream>& stream, |
| 48 const PipelineStatusCB& status_cb) { | 47 const PipelineStatusCB& status_cb) { |
| 49 if (!message_loop_->BelongsToCurrentThread()) { | 48 DVLOG(2) << "Initialize()"; |
| 50 message_loop_->PostTask(FROM_HERE, base::Bind( | 49 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 51 &DecryptingDemuxerStream::DoInitialize, this, stream, status_cb)); | 50 DCHECK_EQ(state_, kUninitialized) << state_; |
| 52 return; | 51 |
| 53 } | 52 DCHECK(!demuxer_stream_); |
| 54 DoInitialize(stream, status_cb); | 53 demuxer_stream_ = stream; |
| 54 init_cb_ = status_cb; | |
| 55 | |
| 56 InitializeDecoderConfig(); | |
| 57 | |
| 58 state_ = kDecryptorRequested; | |
| 59 set_decryptor_ready_cb_.Run( | |
| 60 BIND_TO_LOOP(&DecryptingDemuxerStream::SetDecryptor)); | |
| 55 } | 61 } |
| 56 | 62 |
| 57 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { | 63 void DecryptingDemuxerStream::Read(const ReadCB& read_cb) { |
| 58 DVLOG(3) << "Read()"; | 64 DVLOG(3) << "Read()"; |
| 59 DCHECK(message_loop_->BelongsToCurrentThread()); | 65 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 60 DCHECK_EQ(state_, kIdle) << state_; | 66 DCHECK_EQ(state_, kIdle) << state_; |
| 61 DCHECK(!read_cb.is_null()); | 67 DCHECK(!read_cb.is_null()); |
| 62 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported."; | 68 CHECK(read_cb_.is_null()) << "Overlapping reads are not supported."; |
| 63 | 69 |
| 64 read_cb_ = read_cb; | 70 read_cb_ = read_cb; |
| 65 state_ = kPendingDemuxerRead; | 71 state_ = kPendingDemuxerRead; |
| 66 demuxer_stream_->Read( | 72 demuxer_stream_->Read( |
| 67 base::Bind(&DecryptingDemuxerStream::DecryptBuffer, this)); | 73 base::Bind(&DecryptingDemuxerStream::DecryptBuffer, this)); |
| 68 } | 74 } |
| 69 | 75 |
| 70 void DecryptingDemuxerStream::Reset(const base::Closure& closure) { | 76 void DecryptingDemuxerStream::Reset(const base::Closure& closure) { |
| 71 if (!message_loop_->BelongsToCurrentThread()) { | |
| 72 message_loop_->PostTask(FROM_HERE, base::Bind( | |
| 73 &DecryptingDemuxerStream::Reset, this, closure)); | |
| 74 return; | |
| 75 } | |
| 76 | |
| 77 DVLOG(2) << "Reset() - state: " << state_; | 77 DVLOG(2) << "Reset() - state: " << state_; |
| 78 DCHECK(message_loop_->BelongsToCurrentThread()); | |
| 78 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; | 79 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; |
| 79 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. | 80 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. |
| 80 DCHECK(reset_cb_.is_null()); | 81 DCHECK(reset_cb_.is_null()); |
| 81 | 82 |
| 82 reset_cb_ = BindToCurrentLoop(closure); | 83 reset_cb_ = BindToCurrentLoop(closure); |
| 83 | 84 |
| 84 decryptor_->CancelDecrypt(GetDecryptorStreamType()); | 85 decryptor_->CancelDecrypt(GetDecryptorStreamType()); |
| 85 | 86 |
| 86 // Reset() cannot complete if the read callback is still pending. | 87 // Reset() cannot complete if the read callback is still pending. |
| 87 // Defer the resetting process in this case. The |reset_cb_| will be fired | 88 // Defer the resetting process in this case. The |reset_cb_| will be fired |
| 88 // after the read callback is fired - see DoDecryptBuffer() and | 89 // after the read callback is fired - see DoDecryptBuffer() and |
| 89 // DoDeliverBuffer(). | 90 // DoDeliverBuffer(). |
| 90 if (state_ == kPendingDemuxerRead || state_ == kPendingDecrypt) { | 91 if (state_ == kPendingDemuxerRead || state_ == kPendingDecrypt) { |
| 91 DCHECK(!read_cb_.is_null()); | 92 DCHECK(!read_cb_.is_null()); |
| 92 return; | 93 return; |
| 93 } | 94 } |
| 94 | 95 |
| 95 if (state_ == kWaitingForKey) { | 96 if (state_ == kWaitingForKey) { |
| 96 DCHECK(!read_cb_.is_null()); | 97 DCHECK(!read_cb_.is_null()); |
| 97 pending_buffer_to_decrypt_ = NULL; | 98 pending_buffer_to_decrypt_ = NULL; |
| 98 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 99 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 99 } | 100 } |
| 100 | 101 |
| 101 DCHECK(read_cb_.is_null()); | 102 DCHECK(read_cb_.is_null()); |
| 102 DoReset(); | 103 DoReset(); |
| 103 } | 104 } |
| 104 | 105 |
| 105 const AudioDecoderConfig& DecryptingDemuxerStream::audio_decoder_config() { | 106 const AudioDecoderConfig& DecryptingDemuxerStream::audio_decoder_config() { |
| 106 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; | 107 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; |
| 107 CHECK_EQ(stream_type_, AUDIO); | 108 CHECK_EQ(demuxer_stream_->type(), AUDIO); |
|
ddorwin
2013/04/17 21:45:47
Do we need to protect against demuxer_stream_ bein
xhwang
2013/04/17 22:14:47
I think audio_decoder_config should only be called
| |
| 108 return *audio_config_; | 109 return *audio_config_; |
| 109 } | 110 } |
| 110 | 111 |
| 111 const VideoDecoderConfig& DecryptingDemuxerStream::video_decoder_config() { | 112 const VideoDecoderConfig& DecryptingDemuxerStream::video_decoder_config() { |
| 112 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; | 113 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; |
| 113 CHECK_EQ(stream_type_, VIDEO); | 114 CHECK_EQ(demuxer_stream_->type(), VIDEO); |
| 114 return *video_config_; | 115 return *video_config_; |
| 115 } | 116 } |
| 116 | 117 |
| 117 DemuxerStream::Type DecryptingDemuxerStream::type() { | 118 DemuxerStream::Type DecryptingDemuxerStream::type() { |
| 118 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; | 119 DCHECK(state_ != kUninitialized && state_ != kDecryptorRequested) << state_; |
| 119 return stream_type_; | 120 return demuxer_stream_->type(); |
| 120 } | 121 } |
| 121 | 122 |
| 122 void DecryptingDemuxerStream::EnableBitstreamConverter() { | 123 void DecryptingDemuxerStream::EnableBitstreamConverter() { |
| 123 demuxer_stream_->EnableBitstreamConverter(); | 124 demuxer_stream_->EnableBitstreamConverter(); |
| 124 } | 125 } |
| 125 | 126 |
| 126 DecryptingDemuxerStream::~DecryptingDemuxerStream() {} | 127 DecryptingDemuxerStream::~DecryptingDemuxerStream() {} |
| 127 | 128 |
| 128 void DecryptingDemuxerStream::DoInitialize( | |
| 129 const scoped_refptr<DemuxerStream>& stream, | |
| 130 const PipelineStatusCB& status_cb) { | |
| 131 DVLOG(2) << "DoInitialize()"; | |
| 132 DCHECK(message_loop_->BelongsToCurrentThread()); | |
| 133 DCHECK_EQ(state_, kUninitialized) << state_; | |
| 134 | |
| 135 DCHECK(!demuxer_stream_); | |
| 136 demuxer_stream_ = stream; | |
| 137 stream_type_ = stream->type(); | |
| 138 init_cb_ = status_cb; | |
| 139 | |
| 140 SetDecoderConfig(stream); | |
| 141 | |
| 142 state_ = kDecryptorRequested; | |
| 143 set_decryptor_ready_cb_.Run( | |
| 144 BIND_TO_LOOP(&DecryptingDemuxerStream::SetDecryptor)); | |
| 145 } | |
| 146 | |
| 147 void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) { | 129 void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) { |
| 148 DVLOG(2) << "SetDecryptor()"; | 130 DVLOG(2) << "SetDecryptor()"; |
| 149 DCHECK(message_loop_->BelongsToCurrentThread()); | 131 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 150 DCHECK_EQ(state_, kDecryptorRequested) << state_; | 132 DCHECK_EQ(state_, kDecryptorRequested) << state_; |
| 151 DCHECK(!init_cb_.is_null()); | 133 DCHECK(!init_cb_.is_null()); |
| 152 DCHECK(!set_decryptor_ready_cb_.is_null()); | 134 DCHECK(!set_decryptor_ready_cb_.is_null()); |
| 153 | 135 |
| 154 set_decryptor_ready_cb_.Reset(); | 136 set_decryptor_ready_cb_.Reset(); |
| 155 decryptor_ = decryptor; | 137 decryptor_ = decryptor; |
| 156 | 138 |
| 157 decryptor_->RegisterNewKeyCB( | 139 decryptor_->RegisterNewKeyCB( |
| 158 GetDecryptorStreamType(), | 140 GetDecryptorStreamType(), |
| 159 BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded)); | 141 BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded)); |
| 160 | 142 |
| 161 state_ = kIdle; | 143 state_ = kIdle; |
| 162 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 144 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 163 } | 145 } |
| 164 | 146 |
| 165 void DecryptingDemuxerStream::DecryptBuffer( | 147 void DecryptingDemuxerStream::DecryptBuffer( |
| 166 DemuxerStream::Status status, | 148 DemuxerStream::Status status, |
| 167 const scoped_refptr<DecoderBuffer>& buffer) { | 149 const scoped_refptr<DecoderBuffer>& buffer) { |
| 168 // In theory, we don't need to force post the task here, because we do a | 150 DVLOG(3) << "DecryptBuffer()"; |
| 169 // force task post in DeliverBuffer(). Therefore, even if | |
| 170 // demuxer_stream_->Read() execute the read callback on the same execution | |
| 171 // stack we are still fine. But it looks like a force post task makes the | |
| 172 // logic more understandable and manageable, so why not? | |
| 173 message_loop_->PostTask(FROM_HERE, base::Bind( | |
| 174 &DecryptingDemuxerStream::DoDecryptBuffer, this, status, buffer)); | |
| 175 } | |
| 176 | |
| 177 void DecryptingDemuxerStream::DoDecryptBuffer( | |
| 178 DemuxerStream::Status status, | |
| 179 const scoped_refptr<DecoderBuffer>& buffer) { | |
| 180 DVLOG(3) << "DoDecryptBuffer()"; | |
| 181 DCHECK(message_loop_->BelongsToCurrentThread()); | 151 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 182 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; | 152 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; |
| 183 DCHECK(!read_cb_.is_null()); | 153 DCHECK(!read_cb_.is_null()); |
| 184 DCHECK_EQ(buffer != NULL, status == kOk) << status; | 154 DCHECK_EQ(buffer != NULL, status == kOk) << status; |
| 185 | 155 |
| 186 if (!reset_cb_.is_null()) { | 156 if (!reset_cb_.is_null()) { |
| 187 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 157 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 188 DoReset(); | 158 DoReset(); |
| 189 return; | 159 return; |
| 190 } | 160 } |
| 191 | 161 |
| 192 if (status == kAborted) { | 162 if (status == kAborted) { |
| 193 DVLOG(2) << "DoDecryptBuffer() - kAborted."; | 163 DVLOG(2) << "DoDecryptBuffer() - kAborted."; |
| 194 state_ = kIdle; | 164 state_ = kIdle; |
| 195 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 165 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); |
| 196 return; | 166 return; |
| 197 } | 167 } |
| 198 | 168 |
| 199 if (status == kConfigChanged) { | 169 if (status == kConfigChanged) { |
| 200 DVLOG(2) << "DoDecryptBuffer() - kConfigChanged."; | 170 DVLOG(2) << "DoDecryptBuffer() - kConfigChanged."; |
| 201 DCHECK_EQ(demuxer_stream_->type(), stream_type_); | 171 DCHECK_EQ(demuxer_stream_->type() == AUDIO, audio_config_ != NULL); |
| 172 DCHECK_EQ(demuxer_stream_->type() == VIDEO, video_config_ != NULL); | |
| 202 | 173 |
| 203 // Update the decoder config, which the decoder will use when it is notified | 174 // Update the decoder config, which the decoder will use when it is notified |
| 204 // of kConfigChanged. | 175 // of kConfigChanged. |
| 205 SetDecoderConfig(demuxer_stream_); | 176 InitializeDecoderConfig(); |
| 206 state_ = kIdle; | 177 state_ = kIdle; |
| 207 base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL); | 178 base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL); |
| 208 return; | 179 return; |
| 209 } | 180 } |
| 210 | 181 |
| 211 if (buffer->IsEndOfStream()) { | 182 if (buffer->IsEndOfStream()) { |
| 212 DVLOG(2) << "DoDecryptBuffer() - EOS buffer."; | 183 DVLOG(2) << "DoDecryptBuffer() - EOS buffer."; |
| 213 state_ = kIdle; | 184 state_ = kIdle; |
| 214 base::ResetAndReturn(&read_cb_).Run(status, buffer); | 185 base::ResetAndReturn(&read_cb_).Run(status, buffer); |
| 215 return; | 186 return; |
| 216 } | 187 } |
| 217 | 188 |
| 218 pending_buffer_to_decrypt_ = buffer; | 189 pending_buffer_to_decrypt_ = buffer; |
| 219 state_ = kPendingDecrypt; | 190 state_ = kPendingDecrypt; |
| 220 DecryptPendingBuffer(); | 191 DecryptPendingBuffer(); |
| 221 } | 192 } |
| 222 | 193 |
| 223 void DecryptingDemuxerStream::DecryptPendingBuffer() { | 194 void DecryptingDemuxerStream::DecryptPendingBuffer() { |
| 224 DCHECK(message_loop_->BelongsToCurrentThread()); | 195 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 225 DCHECK_EQ(state_, kPendingDecrypt) << state_; | 196 DCHECK_EQ(state_, kPendingDecrypt) << state_; |
| 226 decryptor_->Decrypt( | 197 decryptor_->Decrypt( |
| 227 GetDecryptorStreamType(), | 198 GetDecryptorStreamType(), |
| 228 pending_buffer_to_decrypt_, | 199 pending_buffer_to_decrypt_, |
| 229 base::Bind(&DecryptingDemuxerStream::DeliverBuffer, this)); | 200 BIND_TO_LOOP(&DecryptingDemuxerStream::DeliverBuffer)); |
|
xhwang
2013/04/17 22:14:47
Now I feel bad about AesDecryptor firing callbacks
| |
| 230 } | 201 } |
| 231 | 202 |
| 232 void DecryptingDemuxerStream::DeliverBuffer( | 203 void DecryptingDemuxerStream::DeliverBuffer( |
| 233 Decryptor::Status status, | 204 Decryptor::Status status, |
| 234 const scoped_refptr<DecoderBuffer>& decrypted_buffer) { | 205 const scoped_refptr<DecoderBuffer>& decrypted_buffer) { |
| 235 // We need to force task post here because the DecryptCB can be executed | 206 DVLOG(3) << "DeliverBuffer() - status: " << status; |
|
ddorwin
2013/04/17 21:45:47
Synchronous calls from Reset() are no longer a con
xhwang
2013/04/17 22:14:47
The BIND_TO_LOOP force posts the DecryptCB so we s
| |
| 236 // synchronously in Reset(). Instead of using more complicated logic in | |
| 237 // those function to fix it, why not force task post here to make everything | |
| 238 // simple and clear? | |
| 239 message_loop_->PostTask(FROM_HERE, base::Bind( | |
| 240 &DecryptingDemuxerStream::DoDeliverBuffer, this, | |
| 241 status, decrypted_buffer)); | |
| 242 } | |
| 243 | |
| 244 void DecryptingDemuxerStream::DoDeliverBuffer( | |
| 245 Decryptor::Status status, | |
| 246 const scoped_refptr<DecoderBuffer>& decrypted_buffer) { | |
| 247 DVLOG(3) << "DoDeliverBuffer() - status: " << status; | |
| 248 DCHECK(message_loop_->BelongsToCurrentThread()); | 207 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 249 DCHECK_EQ(state_, kPendingDecrypt) << state_; | 208 DCHECK_EQ(state_, kPendingDecrypt) << state_; |
| 250 DCHECK_NE(status, Decryptor::kNeedMoreData); | 209 DCHECK_NE(status, Decryptor::kNeedMoreData); |
| 251 DCHECK(!read_cb_.is_null()); | 210 DCHECK(!read_cb_.is_null()); |
| 252 DCHECK(pending_buffer_to_decrypt_); | 211 DCHECK(pending_buffer_to_decrypt_); |
| 253 | 212 |
| 254 bool need_to_try_again_if_nokey = key_added_while_decrypt_pending_; | 213 bool need_to_try_again_if_nokey = key_added_while_decrypt_pending_; |
| 255 key_added_while_decrypt_pending_ = false; | 214 key_added_while_decrypt_pending_ = false; |
| 256 | 215 |
| 257 if (!reset_cb_.is_null()) { | 216 if (!reset_cb_.is_null()) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 } | 263 } |
| 305 | 264 |
| 306 void DecryptingDemuxerStream::DoReset() { | 265 void DecryptingDemuxerStream::DoReset() { |
| 307 DCHECK(init_cb_.is_null()); | 266 DCHECK(init_cb_.is_null()); |
| 308 DCHECK(read_cb_.is_null()); | 267 DCHECK(read_cb_.is_null()); |
| 309 state_ = kIdle; | 268 state_ = kIdle; |
| 310 base::ResetAndReturn(&reset_cb_).Run(); | 269 base::ResetAndReturn(&reset_cb_).Run(); |
| 311 } | 270 } |
| 312 | 271 |
| 313 Decryptor::StreamType DecryptingDemuxerStream::GetDecryptorStreamType() const { | 272 Decryptor::StreamType DecryptingDemuxerStream::GetDecryptorStreamType() const { |
| 314 DCHECK(stream_type_ == AUDIO || stream_type_ == VIDEO); | 273 if (demuxer_stream_->type() == AUDIO) |
| 315 return stream_type_ == AUDIO ? Decryptor::kAudio : Decryptor::kVideo; | 274 return Decryptor::kAudio; |
| 275 | |
| 276 DCHECK_EQ(demuxer_stream_->type(), VIDEO); | |
| 277 return Decryptor::kVideo; | |
| 316 } | 278 } |
| 317 | 279 |
| 318 void DecryptingDemuxerStream::SetDecoderConfig( | 280 void DecryptingDemuxerStream::InitializeDecoderConfig() { |
| 319 const scoped_refptr<DemuxerStream>& stream) { | |
| 320 // The decoder selector or upstream demuxer make sure the stream is valid and | 281 // The decoder selector or upstream demuxer make sure the stream is valid and |
| 321 // potentially encrypted. | 282 // potentially encrypted. |
| 322 DCHECK(IsStreamValidAndEncrypted(stream)); | 283 DCHECK(IsStreamValidAndEncrypted(demuxer_stream_)); |
| 323 | 284 |
| 324 switch (stream_type_) { | 285 switch (demuxer_stream_->type()) { |
| 325 case AUDIO: { | 286 case AUDIO: { |
| 326 const AudioDecoderConfig& input_audio_config = | 287 const AudioDecoderConfig& input_audio_config = |
| 327 stream->audio_decoder_config(); | 288 demuxer_stream_->audio_decoder_config(); |
| 328 audio_config_.reset(new AudioDecoderConfig()); | 289 audio_config_.reset(new AudioDecoderConfig()); |
| 329 audio_config_->Initialize(input_audio_config.codec(), | 290 audio_config_->Initialize(input_audio_config.codec(), |
| 330 input_audio_config.sample_format(), | 291 input_audio_config.sample_format(), |
| 331 input_audio_config.channel_layout(), | 292 input_audio_config.channel_layout(), |
| 332 input_audio_config.samples_per_second(), | 293 input_audio_config.samples_per_second(), |
| 333 input_audio_config.extra_data(), | 294 input_audio_config.extra_data(), |
| 334 input_audio_config.extra_data_size(), | 295 input_audio_config.extra_data_size(), |
| 335 false, // Output audio is not encrypted. | 296 false, // Output audio is not encrypted. |
| 336 false); | 297 false); |
| 337 break; | 298 break; |
| 338 } | 299 } |
| 339 | 300 |
| 340 case VIDEO: { | 301 case VIDEO: { |
| 341 const VideoDecoderConfig& input_video_config = | 302 const VideoDecoderConfig& input_video_config = |
| 342 stream->video_decoder_config(); | 303 demuxer_stream_->video_decoder_config(); |
| 343 video_config_.reset(new VideoDecoderConfig()); | 304 video_config_.reset(new VideoDecoderConfig()); |
| 344 video_config_->Initialize(input_video_config.codec(), | 305 video_config_->Initialize(input_video_config.codec(), |
| 345 input_video_config.profile(), | 306 input_video_config.profile(), |
| 346 input_video_config.format(), | 307 input_video_config.format(), |
| 347 input_video_config.coded_size(), | 308 input_video_config.coded_size(), |
| 348 input_video_config.visible_rect(), | 309 input_video_config.visible_rect(), |
| 349 input_video_config.natural_size(), | 310 input_video_config.natural_size(), |
| 350 input_video_config.extra_data(), | 311 input_video_config.extra_data(), |
| 351 input_video_config.extra_data_size(), | 312 input_video_config.extra_data_size(), |
| 352 false, // Output video is not encrypted. | 313 false, // Output video is not encrypted. |
| 353 false); | 314 false); |
| 354 break; | 315 break; |
| 355 } | 316 } |
| 356 | 317 |
| 357 default: | 318 default: |
| 358 NOTREACHED(); | 319 NOTREACHED(); |
| 359 return; | 320 return; |
| 360 } | 321 } |
| 361 } | 322 } |
| 362 | 323 |
| 363 } // namespace media | 324 } // namespace media |
| OLD | NEW |