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

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

Issue 11745026: Encrypted Media: Add config change support in DecryptingVideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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_video_decoder.h" 5 #include "media/filters/decrypting_video_decoder.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/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 } 79 }
80 80
81 state_ = kPendingDemuxerRead; 81 state_ = kPendingDemuxerRead;
82 ReadFromDemuxerStream(); 82 ReadFromDemuxerStream();
83 } 83 }
84 84
85 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { 85 void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
86 DVLOG(2) << "Reset() - state: " << state_; 86 DVLOG(2) << "Reset() - state: " << state_;
87 DCHECK(message_loop_->BelongsToCurrentThread()); 87 DCHECK(message_loop_->BelongsToCurrentThread());
88 DCHECK(state_ == kIdle || 88 DCHECK(state_ == kIdle ||
89 state_ == kPendingConfigChange ||
89 state_ == kPendingDemuxerRead || 90 state_ == kPendingDemuxerRead ||
90 state_ == kPendingDecode || 91 state_ == kPendingDecode ||
91 state_ == kWaitingForKey || 92 state_ == kWaitingForKey ||
92 state_ == kDecodeFinished) << state_; 93 state_ == kDecodeFinished) << state_;
93 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 94 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
94 DCHECK(reset_cb_.is_null()); 95 DCHECK(reset_cb_.is_null());
95 96
96 reset_cb_ = BindToCurrentLoop(closure); 97 reset_cb_ = BindToCurrentLoop(closure);
97 98
98 decryptor_->ResetDecoder(Decryptor::kVideo); 99 decryptor_->ResetDecoder(Decryptor::kVideo);
99 100
100 // Reset() cannot complete if the read callback is still pending. 101 // Reset() cannot complete if the read callback is still pending.
101 // Defer the resetting process in this case. The |reset_cb_| will be fired 102 // Defer the resetting process in this case. The |reset_cb_| will be fired
102 // after the read callback is fired - see DecryptAndDecodeBuffer() and 103 // after the read callback is fired - see DecryptAndDecodeBuffer() and
103 // DeliverFrame(). 104 // DeliverFrame().
104 if (state_ == kPendingDemuxerRead || state_ == kPendingDecode) { 105 if (state_ == kPendingConfigChange ||
106 state_ == kPendingDemuxerRead ||
107 state_ == kPendingDecode) {
105 DCHECK(!read_cb_.is_null()); 108 DCHECK(!read_cb_.is_null());
106 return; 109 return;
107 } 110 }
108 111
109 if (state_ == kWaitingForKey) { 112 if (state_ == kWaitingForKey) {
110 DCHECK(!read_cb_.is_null()); 113 DCHECK(!read_cb_.is_null());
111 pending_buffer_to_decode_ = NULL; 114 pending_buffer_to_decode_ = NULL;
112 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 115 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
113 } 116 }
114 117
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 191 }
189 192
190 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop( 193 decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop(
191 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, this))); 194 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, this)));
192 195
193 // Success! 196 // Success!
194 state_ = kIdle; 197 state_ = kIdle;
195 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 198 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
196 } 199 }
197 200
201 void DecryptingVideoDecoder::FinishConfigChange(bool success) {
202 DVLOG(2) << "FinishConfigChange()";
203 DCHECK(message_loop_->BelongsToCurrentThread());
204
205 if (state_ == kStopped)
206 return;
207
208 DCHECK_EQ(state_, kPendingConfigChange) << state_;
209 DCHECK(!read_cb_.is_null());
210
211 if (success) {
212 if (reset_cb_.is_null()) {
ddorwin 2013/01/04 17:59:01 Could you also eliminate this indent by moving 222
xhwang 2013/01/05 00:09:55 Done.
213 state_ = kPendingDemuxerRead;
214 ReadFromDemuxerStream();
215 } else {
acolwell GONE FROM CHROMIUM 2013/01/04 16:03:20 nit: add return above and drop else
ddorwin 2013/01/04 17:59:01 Maybe even invert the logic to if (!reset_cb_.is_n
xhwang 2013/01/05 00:09:55 Done.
xhwang 2013/01/05 00:09:55 Done.
216 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
217 DoReset();
218 }
219 return;
220 }
221
222 // Config change failed.
223 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
224 state_ = kDecodeFinished;
225 if (!reset_cb_.is_null())
226 base::ResetAndReturn(&reset_cb_).Run();
227 }
228
198 void DecryptingVideoDecoder::ReadFromDemuxerStream() { 229 void DecryptingVideoDecoder::ReadFromDemuxerStream() {
199 DCHECK(message_loop_->BelongsToCurrentThread()); 230 DCHECK(message_loop_->BelongsToCurrentThread());
200 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 231 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
201 DCHECK(!read_cb_.is_null()); 232 DCHECK(!read_cb_.is_null());
202 233
203 demuxer_stream_->Read( 234 demuxer_stream_->Read(
204 base::Bind(&DecryptingVideoDecoder::DecryptAndDecodeBuffer, this)); 235 base::Bind(&DecryptingVideoDecoder::DecryptAndDecodeBuffer, this));
205 } 236 }
206 237
207 void DecryptingVideoDecoder::DecryptAndDecodeBuffer( 238 void DecryptingVideoDecoder::DecryptAndDecodeBuffer(
208 DemuxerStream::Status status, 239 DemuxerStream::Status status,
209 const scoped_refptr<DecoderBuffer>& buffer) { 240 const scoped_refptr<DecoderBuffer>& buffer) {
210 DVLOG(3) << "DecryptAndDecodeBuffer()"; 241 DVLOG(3) << "DecryptAndDecodeBuffer()";
211 DCHECK(message_loop_->BelongsToCurrentThread()); 242 DCHECK(message_loop_->BelongsToCurrentThread());
212 243
213 if (state_ == kStopped) 244 if (state_ == kStopped)
214 return; 245 return;
215 246
216 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 247 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
217 DCHECK(!read_cb_.is_null()); 248 DCHECK(!read_cb_.is_null());
218 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; 249 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status;
219 250
220 if (!reset_cb_.is_null()) { 251 if (status == DemuxerStream::kConfigChanged) {
221 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 252 DVLOG(2) << "DecryptAndDecodeBuffer() - kConfigChanged";
222 if (!reset_cb_.is_null()) 253
223 DoReset(); 254 scoped_ptr<VideoDecoderConfig> scoped_config(new VideoDecoderConfig());
255 scoped_config->CopyFrom(demuxer_stream_->video_decoder_config());
256
257 state_ = kPendingConfigChange;
258 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
259 decryptor_->InitializeVideoDecoder(
acolwell GONE FROM CHROMIUM 2013/01/04 16:03:20 nit: In a different CL, consider changing the sign
xhwang 2013/01/05 00:09:55 The original reason that I use the scoped_ptr<> he
acolwell GONE FROM CHROMIUM 2013/01/05 01:17:12 I don't understand. If you make the parameter cons
xhwang 2013/01/05 04:03:51 I remember the original reason is that in PpapiDec
260 scoped_config.Pass(), BindToCurrentLoop(base::Bind(
261 &DecryptingVideoDecoder::FinishConfigChange, this)));
224 return; 262 return;
225 } 263 }
226 264
265 if (!reset_cb_.is_null()) {
266 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
267 DoReset();
268 return;
269 }
270
227 if (status == DemuxerStream::kAborted) { 271 if (status == DemuxerStream::kAborted) {
228 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted"; 272 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted";
229 state_ = kIdle; 273 state_ = kIdle;
230 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 274 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
231 return; 275 return;
232 } 276 }
233 277
234 if (status == DemuxerStream::kConfigChanged) {
235 // TODO(xhwang): Add config change support.
236 // The |state_| is chosen to be kDecodeFinished here to be consistent with
237 // the implementation of FFmpegVideoDecoder.
238 DVLOG(2) << "DecryptAndDecodeBuffer() - kConfigChanged";
239 state_ = kDecodeFinished;
240 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
241 return;
242 }
243
244 DCHECK_EQ(status, DemuxerStream::kOk); 278 DCHECK_EQ(status, DemuxerStream::kOk);
245 pending_buffer_to_decode_ = buffer; 279 pending_buffer_to_decode_ = buffer;
246 state_ = kPendingDecode; 280 state_ = kPendingDecode;
247 DecodePendingBuffer(); 281 DecodePendingBuffer();
248 } 282 }
249 283
250 void DecryptingVideoDecoder::DecodePendingBuffer() { 284 void DecryptingVideoDecoder::DecodePendingBuffer() {
251 DCHECK(message_loop_->BelongsToCurrentThread()); 285 DCHECK(message_loop_->BelongsToCurrentThread());
252 DCHECK_EQ(state_, kPendingDecode) << state_; 286 DCHECK_EQ(state_, kPendingDecode) << state_;
253 TRACE_EVENT_ASYNC_BEGIN0( 287 TRACE_EVENT_ASYNC_BEGIN0(
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 } 390 }
357 391
358 void DecryptingVideoDecoder::DoReset() { 392 void DecryptingVideoDecoder::DoReset() {
359 DCHECK(init_cb_.is_null()); 393 DCHECK(init_cb_.is_null());
360 DCHECK(read_cb_.is_null()); 394 DCHECK(read_cb_.is_null());
361 state_ = kIdle; 395 state_ = kIdle;
362 base::ResetAndReturn(&reset_cb_).Run(); 396 base::ResetAndReturn(&reset_cb_).Run();
363 } 397 }
364 398
365 } // namespace media 399 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698