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

Side by Side Diff: media/filters/decrypting_demuxer_stream.cc

Issue 11722008: Encrypted Media: Support config change in DecryptingDemuxerStream. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: resolved comments Created 7 years, 11 months 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 "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_proxy.h" 11 #include "base/message_loop_proxy.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, this)) 23 media::BindToLoop(message_loop_, base::Bind(function, this))
24 24
25 static bool IsStreamValidAndEncrypted(
26 const scoped_refptr<DemuxerStream>& stream) {
27 return ((stream->type() == DemuxerStream::AUDIO &&
28 stream->audio_decoder_config().IsValidConfig() &&
29 stream->audio_decoder_config().is_encrypted()) ||
30 (stream->type() == DemuxerStream::VIDEO &&
31 stream->video_decoder_config().IsValidConfig() &&
32 stream->video_decoder_config().is_encrypted()));
33 }
34
25 DecryptingDemuxerStream::DecryptingDemuxerStream( 35 DecryptingDemuxerStream::DecryptingDemuxerStream(
26 const scoped_refptr<base::MessageLoopProxy>& message_loop, 36 const scoped_refptr<base::MessageLoopProxy>& message_loop,
27 const SetDecryptorReadyCB& set_decryptor_ready_cb) 37 const SetDecryptorReadyCB& set_decryptor_ready_cb)
28 : message_loop_(message_loop), 38 : message_loop_(message_loop),
29 state_(kUninitialized), 39 state_(kUninitialized),
30 stream_type_(UNKNOWN), 40 stream_type_(UNKNOWN),
31 set_decryptor_ready_cb_(set_decryptor_ready_cb), 41 set_decryptor_ready_cb_(set_decryptor_ready_cb),
32 decryptor_(NULL), 42 decryptor_(NULL),
33 key_added_while_decrypt_pending_(false) { 43 key_added_while_decrypt_pending_(false) {
34 } 44 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 125
116 DecryptingDemuxerStream::~DecryptingDemuxerStream() {} 126 DecryptingDemuxerStream::~DecryptingDemuxerStream() {}
117 127
118 void DecryptingDemuxerStream::DoInitialize( 128 void DecryptingDemuxerStream::DoInitialize(
119 const scoped_refptr<DemuxerStream>& stream, 129 const scoped_refptr<DemuxerStream>& stream,
120 const PipelineStatusCB& status_cb) { 130 const PipelineStatusCB& status_cb) {
121 DVLOG(2) << "DoInitialize()"; 131 DVLOG(2) << "DoInitialize()";
122 DCHECK(message_loop_->BelongsToCurrentThread()); 132 DCHECK(message_loop_->BelongsToCurrentThread());
123 DCHECK_EQ(state_, kUninitialized) << state_; 133 DCHECK_EQ(state_, kUninitialized) << state_;
124 134
125 // Only valid potentially encrypted audio or video stream is accepted. 135 // Decoder selector makes sure the stream is valid and potentially encrypted.
126 if (!((stream->type() == AUDIO && 136 DCHECK(IsStreamValidAndEncrypted(stream));
ddorwin 2013/01/03 17:48:29 WDYT about moving this inside SetDecoderConfig() n
xhwang 2013/01/03 18:16:04 Done.
127 stream->audio_decoder_config().IsValidConfig() &&
128 stream->audio_decoder_config().is_encrypted()) ||
129 (stream->type() == VIDEO &&
130 stream->video_decoder_config().IsValidConfig() &&
131 stream->video_decoder_config().is_encrypted()))) {
132 status_cb.Run(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
133 return;
134 }
135 137
136 DCHECK(!demuxer_stream_); 138 DCHECK(!demuxer_stream_);
137 demuxer_stream_ = stream; 139 demuxer_stream_ = stream;
138 stream_type_ = stream->type(); 140 stream_type_ = stream->type();
139 init_cb_ = status_cb; 141 init_cb_ = status_cb;
140 142
143 SetDecoderConfig();
144
141 state_ = kDecryptorRequested; 145 state_ = kDecryptorRequested;
142 set_decryptor_ready_cb_.Run( 146 set_decryptor_ready_cb_.Run(
143 BIND_TO_LOOP(&DecryptingDemuxerStream::SetDecryptor)); 147 BIND_TO_LOOP(&DecryptingDemuxerStream::SetDecryptor));
144 } 148 }
145 149
146 void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) { 150 void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) {
147 DVLOG(2) << "SetDecryptor()"; 151 DVLOG(2) << "SetDecryptor()";
148 DCHECK(message_loop_->BelongsToCurrentThread()); 152 DCHECK(message_loop_->BelongsToCurrentThread());
149 DCHECK_EQ(state_, kDecryptorRequested) << state_; 153 DCHECK_EQ(state_, kDecryptorRequested) << state_;
150 DCHECK(!init_cb_.is_null()); 154 DCHECK(!init_cb_.is_null());
151 DCHECK(!set_decryptor_ready_cb_.is_null()); 155 DCHECK(!set_decryptor_ready_cb_.is_null());
152 156
153 set_decryptor_ready_cb_.Reset(); 157 set_decryptor_ready_cb_.Reset();
154 decryptor_ = decryptor; 158 decryptor_ = decryptor;
155 159
156 switch (stream_type_) {
157 case AUDIO: {
158 const AudioDecoderConfig& input_audio_config =
159 demuxer_stream_->audio_decoder_config();
160 audio_config_.reset(new AudioDecoderConfig());
161 audio_config_->Initialize(input_audio_config.codec(),
162 input_audio_config.bits_per_channel(),
163 input_audio_config.channel_layout(),
164 input_audio_config.samples_per_second(),
165 input_audio_config.extra_data(),
166 input_audio_config.extra_data_size(),
167 false, // Output audio is not encrypted.
168 false);
169 break;
170 }
171
172 case VIDEO: {
173 const VideoDecoderConfig& input_video_config =
174 demuxer_stream_->video_decoder_config();
175 video_config_.reset(new VideoDecoderConfig());
176 video_config_->Initialize(input_video_config.codec(),
177 input_video_config.profile(),
178 input_video_config.format(),
179 input_video_config.coded_size(),
180 input_video_config.visible_rect(),
181 input_video_config.natural_size(),
182 input_video_config.extra_data(),
183 input_video_config.extra_data_size(),
184 false, // Output video is not encrypted.
185 false);
186 break;
187 }
188
189 default:
190 NOTREACHED();
191 return;
192 }
193
194 decryptor_->RegisterNewKeyCB( 160 decryptor_->RegisterNewKeyCB(
195 GetDecryptorStreamType(), 161 GetDecryptorStreamType(),
196 BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded)); 162 BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded));
197 163
198 state_ = kIdle; 164 state_ = kIdle;
199 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 165 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
200 } 166 }
201 167
202 void DecryptingDemuxerStream::DecryptBuffer( 168 void DecryptingDemuxerStream::DecryptBuffer(
203 DemuxerStream::Status status, 169 DemuxerStream::Status status,
(...skipping 24 matching lines...) Expand all
228 194
229 if (status == kAborted) { 195 if (status == kAborted) {
230 DVLOG(2) << "DoDecryptBuffer() - kAborted."; 196 DVLOG(2) << "DoDecryptBuffer() - kAborted.";
231 state_ = kIdle; 197 state_ = kIdle;
232 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); 198 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
233 return; 199 return;
234 } 200 }
235 201
236 if (status == kConfigChanged) { 202 if (status == kConfigChanged) {
237 DVLOG(2) << "DoDecryptBuffer() - kConfigChanged."; 203 DVLOG(2) << "DoDecryptBuffer() - kConfigChanged.";
204 DCHECK_EQ(demuxer_stream_->type(), stream_type_);
205 // The demuxer should make sure the stream is still valid and potentially
206 // encrypted.
207 DCHECK(IsStreamValidAndEncrypted(demuxer_stream_));
208
209 // Update the decoder config with the new config.
ddorwin 2013/01/03 17:48:29 This comment doesn't really add anything that the
xhwang 2013/01/03 18:16:04 Done.
210 SetDecoderConfig();
ddorwin 2013/01/03 17:48:29 SetDecoderConfigFromDemuxerStream? Should Set be U
xhwang 2013/01/03 18:16:04 Done.
238 state_ = kIdle; 211 state_ = kIdle;
239 // TODO(xhwang): Support kConfigChanged! 212 base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
240 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
241 return; 213 return;
242 } 214 }
243 215
244 if (buffer->IsEndOfStream()) { 216 if (buffer->IsEndOfStream()) {
245 DVLOG(2) << "DoDecryptBuffer() - EOS buffer."; 217 DVLOG(2) << "DoDecryptBuffer() - EOS buffer.";
246 state_ = kIdle; 218 state_ = kIdle;
247 base::ResetAndReturn(&read_cb_).Run(status, buffer); 219 base::ResetAndReturn(&read_cb_).Run(status, buffer);
248 return; 220 return;
249 } 221 }
250 222
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 DCHECK(read_cb_.is_null()); 313 DCHECK(read_cb_.is_null());
342 state_ = kIdle; 314 state_ = kIdle;
343 base::ResetAndReturn(&reset_cb_).Run(); 315 base::ResetAndReturn(&reset_cb_).Run();
344 } 316 }
345 317
346 Decryptor::StreamType DecryptingDemuxerStream::GetDecryptorStreamType() const { 318 Decryptor::StreamType DecryptingDemuxerStream::GetDecryptorStreamType() const {
347 DCHECK(stream_type_ == AUDIO || stream_type_ == VIDEO); 319 DCHECK(stream_type_ == AUDIO || stream_type_ == VIDEO);
348 return stream_type_ == AUDIO ? Decryptor::kAudio : Decryptor::kVideo; 320 return stream_type_ == AUDIO ? Decryptor::kAudio : Decryptor::kVideo;
349 } 321 }
350 322
323 void DecryptingDemuxerStream::SetDecoderConfig() {
324 switch (stream_type_) {
325 case AUDIO: {
326 const AudioDecoderConfig& input_audio_config =
327 demuxer_stream_->audio_decoder_config();
328 audio_config_.reset(new AudioDecoderConfig());
329 audio_config_->Initialize(input_audio_config.codec(),
330 input_audio_config.bits_per_channel(),
331 input_audio_config.channel_layout(),
332 input_audio_config.samples_per_second(),
333 input_audio_config.extra_data(),
334 input_audio_config.extra_data_size(),
335 false, // Output audio is not encrypted.
336 false);
337 break;
338 }
339
340 case VIDEO: {
341 const VideoDecoderConfig& input_video_config =
342 demuxer_stream_->video_decoder_config();
343 video_config_.reset(new VideoDecoderConfig());
344 video_config_->Initialize(input_video_config.codec(),
345 input_video_config.profile(),
346 input_video_config.format(),
347 input_video_config.coded_size(),
348 input_video_config.visible_rect(),
349 input_video_config.natural_size(),
350 input_video_config.extra_data(),
351 input_video_config.extra_data_size(),
352 false, // Output video is not encrypted.
353 false);
354 break;
355 }
356
357 default:
358 NOTREACHED();
359 return;
360 }
361 }
362
351 } // namespace media 363 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decrypting_demuxer_stream.h ('k') | media/filters/decrypting_demuxer_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698