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

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: remove ffvd changes; will do that in another CL 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 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
213 state_ = kDecodeFinished;
214 if (!reset_cb_.is_null())
215 base::ResetAndReturn(&reset_cb_).Run();
216 return;
217 }
218
219 // Config change succeeded.
220 if (!reset_cb_.is_null()) {
221 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
222 DoReset();
223 return;
224 }
225
226 state_ = kPendingDemuxerRead;
227 ReadFromDemuxerStream();
228 }
229
198 void DecryptingVideoDecoder::ReadFromDemuxerStream() { 230 void DecryptingVideoDecoder::ReadFromDemuxerStream() {
199 DCHECK(message_loop_->BelongsToCurrentThread()); 231 DCHECK(message_loop_->BelongsToCurrentThread());
200 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 232 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
201 DCHECK(!read_cb_.is_null()); 233 DCHECK(!read_cb_.is_null());
202 234
203 demuxer_stream_->Read( 235 demuxer_stream_->Read(
204 base::Bind(&DecryptingVideoDecoder::DecryptAndDecodeBuffer, this)); 236 base::Bind(&DecryptingVideoDecoder::DecryptAndDecodeBuffer, this));
205 } 237 }
206 238
207 void DecryptingVideoDecoder::DecryptAndDecodeBuffer( 239 void DecryptingVideoDecoder::DecryptAndDecodeBuffer(
208 DemuxerStream::Status status, 240 DemuxerStream::Status status,
209 const scoped_refptr<DecoderBuffer>& buffer) { 241 const scoped_refptr<DecoderBuffer>& buffer) {
210 DVLOG(3) << "DecryptAndDecodeBuffer()"; 242 DVLOG(3) << "DecryptAndDecodeBuffer()";
211 DCHECK(message_loop_->BelongsToCurrentThread()); 243 DCHECK(message_loop_->BelongsToCurrentThread());
212 244
213 if (state_ == kStopped) 245 if (state_ == kStopped)
214 return; 246 return;
215 247
216 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 248 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
217 DCHECK(!read_cb_.is_null()); 249 DCHECK(!read_cb_.is_null());
218 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; 250 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status;
219 251
220 if (!reset_cb_.is_null()) { 252 if (status == DemuxerStream::kConfigChanged) {
221 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 253 DVLOG(2) << "DecryptAndDecodeBuffer() - kConfigChanged";
222 if (!reset_cb_.is_null()) 254
223 DoReset(); 255 scoped_ptr<VideoDecoderConfig> scoped_config(new VideoDecoderConfig());
256 scoped_config->CopyFrom(demuxer_stream_->video_decoder_config());
257
258 state_ = kPendingConfigChange;
259 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
260 decryptor_->InitializeVideoDecoder(
261 scoped_config.Pass(), BindToCurrentLoop(base::Bind(
262 &DecryptingVideoDecoder::FinishConfigChange, this)));
224 return; 263 return;
225 } 264 }
226 265
266 if (!reset_cb_.is_null()) {
267 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
268 DoReset();
269 return;
270 }
271
227 if (status == DemuxerStream::kAborted) { 272 if (status == DemuxerStream::kAborted) {
228 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted"; 273 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted";
229 state_ = kIdle; 274 state_ = kIdle;
230 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 275 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
231 return; 276 return;
232 } 277 }
233 278
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); 279 DCHECK_EQ(status, DemuxerStream::kOk);
245 pending_buffer_to_decode_ = buffer; 280 pending_buffer_to_decode_ = buffer;
246 state_ = kPendingDecode; 281 state_ = kPendingDecode;
247 DecodePendingBuffer(); 282 DecodePendingBuffer();
248 } 283 }
249 284
250 void DecryptingVideoDecoder::DecodePendingBuffer() { 285 void DecryptingVideoDecoder::DecodePendingBuffer() {
251 DCHECK(message_loop_->BelongsToCurrentThread()); 286 DCHECK(message_loop_->BelongsToCurrentThread());
252 DCHECK_EQ(state_, kPendingDecode) << state_; 287 DCHECK_EQ(state_, kPendingDecode) << state_;
253 TRACE_EVENT_ASYNC_BEGIN0( 288 TRACE_EVENT_ASYNC_BEGIN0(
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 } 391 }
357 392
358 void DecryptingVideoDecoder::DoReset() { 393 void DecryptingVideoDecoder::DoReset() {
359 DCHECK(init_cb_.is_null()); 394 DCHECK(init_cb_.is_null());
360 DCHECK(read_cb_.is_null()); 395 DCHECK(read_cb_.is_null());
361 state_ = kIdle; 396 state_ = kIdle;
362 base::ResetAndReturn(&reset_cb_).Run(); 397 base::ResetAndReturn(&reset_cb_).Run();
363 } 398 }
364 399
365 } // namespace media 400 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decrypting_video_decoder.h ('k') | media/filters/decrypting_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698