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

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

Issue 65803002: Replace MessageLoopProxy with SingleThreadTaskRunner for media/filters/ + associated code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/video_frame_stream.h" 5 #include "media/filters/video_frame_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/bind_to_loop.h" 12 #include "media/base/bind_to_loop.h"
13 #include "media/base/decoder_buffer.h" 13 #include "media/base/decoder_buffer.h"
14 #include "media/base/demuxer_stream.h" 14 #include "media/base/demuxer_stream.h"
15 #include "media/base/video_decoder_config.h" 15 #include "media/base/video_decoder_config.h"
16 #include "media/filters/decrypting_demuxer_stream.h" 16 #include "media/filters/decrypting_demuxer_stream.h"
17 #include "media/filters/video_decoder_selector.h" 17 #include "media/filters/video_decoder_selector.h"
18 18
19 namespace media { 19 namespace media {
20 20
21 VideoFrameStream::VideoFrameStream( 21 VideoFrameStream::VideoFrameStream(
22 const scoped_refptr<base::MessageLoopProxy>& message_loop, 22 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
23 ScopedVector<VideoDecoder> decoders, 23 ScopedVector<VideoDecoder> decoders,
24 const SetDecryptorReadyCB& set_decryptor_ready_cb) 24 const SetDecryptorReadyCB& set_decryptor_ready_cb)
25 : message_loop_(message_loop), 25 : task_runner_(task_runner),
26 weak_factory_(this), 26 weak_factory_(this),
27 state_(STATE_UNINITIALIZED), 27 state_(STATE_UNINITIALIZED),
28 stream_(NULL), 28 stream_(NULL),
29 decoder_selector_(new VideoDecoderSelector(message_loop, 29 decoder_selector_(new VideoDecoderSelector(task_runner,
30 decoders.Pass(), 30 decoders.Pass(),
31 set_decryptor_ready_cb)) { 31 set_decryptor_ready_cb)) {
32 } 32 }
33 33
34 VideoFrameStream::~VideoFrameStream() { 34 VideoFrameStream::~VideoFrameStream() {
35 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; 35 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_;
36 } 36 }
37 37
38 void VideoFrameStream::Initialize(DemuxerStream* stream, 38 void VideoFrameStream::Initialize(DemuxerStream* stream,
39 const StatisticsCB& statistics_cb, 39 const StatisticsCB& statistics_cb,
40 const InitCB& init_cb) { 40 const InitCB& init_cb) {
41 DVLOG(2) << __FUNCTION__; 41 DVLOG(2) << __FUNCTION__;
42 DCHECK(message_loop_->BelongsToCurrentThread()); 42 DCHECK(task_runner_->BelongsToCurrentThread());
43 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_; 43 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_;
44 DCHECK(init_cb_.is_null()); 44 DCHECK(init_cb_.is_null());
45 DCHECK(!init_cb.is_null()); 45 DCHECK(!init_cb.is_null());
46 46
47 statistics_cb_ = statistics_cb; 47 statistics_cb_ = statistics_cb;
48 init_cb_ = init_cb; 48 init_cb_ = init_cb;
49 stream_ = stream; 49 stream_ = stream;
50 50
51 state_ = STATE_INITIALIZING; 51 state_ = STATE_INITIALIZING;
52 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder. 52 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder.
53 decoder_selector_->SelectVideoDecoder( 53 decoder_selector_->SelectVideoDecoder(
54 stream, 54 stream,
55 base::Bind(&VideoFrameStream::OnDecoderSelected, 55 base::Bind(&VideoFrameStream::OnDecoderSelected,
56 weak_factory_.GetWeakPtr())); 56 weak_factory_.GetWeakPtr()));
57 } 57 }
58 58
59 void VideoFrameStream::Read(const ReadCB& read_cb) { 59 void VideoFrameStream::Read(const ReadCB& read_cb) {
60 DVLOG(2) << __FUNCTION__; 60 DVLOG(2) << __FUNCTION__;
61 DCHECK(message_loop_->BelongsToCurrentThread()); 61 DCHECK(task_runner_->BelongsToCurrentThread());
62 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 62 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
63 state_ == STATE_ERROR) << state_; 63 state_ == STATE_ERROR) << state_;
64 // No two reads in the flight at any time. 64 // No two reads in the flight at any time.
65 DCHECK(read_cb_.is_null()); 65 DCHECK(read_cb_.is_null());
66 // No read during resetting or stopping process. 66 // No read during resetting or stopping process.
67 DCHECK(reset_cb_.is_null()); 67 DCHECK(reset_cb_.is_null());
68 DCHECK(stop_cb_.is_null()); 68 DCHECK(stop_cb_.is_null());
69 69
70 if (state_ == STATE_ERROR) { 70 if (state_ == STATE_ERROR) {
71 message_loop_->PostTask(FROM_HERE, base::Bind( 71 task_runner_->PostTask(FROM_HERE, base::Bind(
72 read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>())); 72 read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>()));
73 return; 73 return;
74 } 74 }
75 75
76 read_cb_ = read_cb; 76 read_cb_ = read_cb;
77 77
78 if (state_ == STATE_FLUSHING_DECODER) { 78 if (state_ == STATE_FLUSHING_DECODER) {
79 FlushDecoder(); 79 FlushDecoder();
80 return; 80 return;
81 } 81 }
82 82
83 ReadFromDemuxerStream(); 83 ReadFromDemuxerStream();
84 } 84 }
85 85
86 void VideoFrameStream::Reset(const base::Closure& closure) { 86 void VideoFrameStream::Reset(const base::Closure& closure) {
87 DVLOG(2) << __FUNCTION__; 87 DVLOG(2) << __FUNCTION__;
88 DCHECK(message_loop_->BelongsToCurrentThread()); 88 DCHECK(task_runner_->BelongsToCurrentThread());
89 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 89 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
90 DCHECK(reset_cb_.is_null()); 90 DCHECK(reset_cb_.is_null());
91 DCHECK(stop_cb_.is_null()); 91 DCHECK(stop_cb_.is_null());
92 92
93 reset_cb_ = closure; 93 reset_cb_ = closure;
94 94
95 // During decoder reinitialization, VideoDecoder does not need to be and 95 // During decoder reinitialization, VideoDecoder does not need to be and
96 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder 96 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
97 // reinitialization. 97 // reinitialization.
98 if (state_ == STATE_REINITIALIZING_DECODER) 98 if (state_ == STATE_REINITIALIZING_DECODER)
(...skipping 14 matching lines...) Expand all
113 decrypting_demuxer_stream_->Reset(base::Bind( 113 decrypting_demuxer_stream_->Reset(base::Bind(
114 &VideoFrameStream::ResetDecoder, weak_factory_.GetWeakPtr())); 114 &VideoFrameStream::ResetDecoder, weak_factory_.GetWeakPtr()));
115 return; 115 return;
116 } 116 }
117 117
118 ResetDecoder(); 118 ResetDecoder();
119 } 119 }
120 120
121 void VideoFrameStream::Stop(const base::Closure& closure) { 121 void VideoFrameStream::Stop(const base::Closure& closure) {
122 DVLOG(2) << __FUNCTION__; 122 DVLOG(2) << __FUNCTION__;
123 DCHECK(message_loop_->BelongsToCurrentThread()); 123 DCHECK(task_runner_->BelongsToCurrentThread());
124 DCHECK_NE(state_, STATE_STOPPED) << state_; 124 DCHECK_NE(state_, STATE_STOPPED) << state_;
125 DCHECK(stop_cb_.is_null()); 125 DCHECK(stop_cb_.is_null());
126 126
127 stop_cb_ = closure; 127 stop_cb_ = closure;
128 128
129 if (state_ == STATE_INITIALIZING) { 129 if (state_ == STATE_INITIALIZING) {
130 decoder_selector_->Abort(); 130 decoder_selector_->Abort();
131 return; 131 return;
132 } 132 }
133 133
134 DCHECK(init_cb_.is_null()); 134 DCHECK(init_cb_.is_null());
135 135
136 // All pending callbacks will be dropped. 136 // All pending callbacks will be dropped.
137 weak_factory_.InvalidateWeakPtrs(); 137 weak_factory_.InvalidateWeakPtrs();
138 138
139 // Post callbacks to prevent reentrance into this object. 139 // Post callbacks to prevent reentrance into this object.
140 if (!read_cb_.is_null()) 140 if (!read_cb_.is_null())
141 message_loop_->PostTask(FROM_HERE, base::Bind( 141 task_runner_->PostTask(FROM_HERE, base::Bind(
142 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<VideoFrame>())); 142 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<VideoFrame>()));
143 if (!reset_cb_.is_null()) 143 if (!reset_cb_.is_null())
144 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); 144 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
145 145
146 if (decrypting_demuxer_stream_) { 146 if (decrypting_demuxer_stream_) {
147 decrypting_demuxer_stream_->Reset(base::Bind( 147 decrypting_demuxer_stream_->Reset(base::Bind(
148 &VideoFrameStream::StopDecoder, weak_factory_.GetWeakPtr())); 148 &VideoFrameStream::StopDecoder, weak_factory_.GetWeakPtr()));
149 return; 149 return;
150 } 150 }
151 151
152 // We may not have a |decoder_| if Stop() was called during initialization. 152 // We may not have a |decoder_| if Stop() was called during initialization.
153 if (decoder_) { 153 if (decoder_) {
154 StopDecoder(); 154 StopDecoder();
155 return; 155 return;
156 } 156 }
157 157
158 state_ = STATE_STOPPED; 158 state_ = STATE_STOPPED;
159 stream_ = NULL; 159 stream_ = NULL;
160 decoder_.reset(); 160 decoder_.reset();
161 decrypting_demuxer_stream_.reset(); 161 decrypting_demuxer_stream_.reset();
162 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 162 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
163 } 163 }
164 164
165 bool VideoFrameStream::CanReadWithoutStalling() const { 165 bool VideoFrameStream::CanReadWithoutStalling() const {
166 DCHECK(message_loop_->BelongsToCurrentThread()); 166 DCHECK(task_runner_->BelongsToCurrentThread());
167 return decoder_->CanReadWithoutStalling(); 167 return decoder_->CanReadWithoutStalling();
168 } 168 }
169 169
170 void VideoFrameStream::OnDecoderSelected( 170 void VideoFrameStream::OnDecoderSelected(
171 scoped_ptr<VideoDecoder> selected_decoder, 171 scoped_ptr<VideoDecoder> selected_decoder,
172 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 172 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
173 DVLOG(2) << __FUNCTION__; 173 DVLOG(2) << __FUNCTION__;
174 DCHECK(message_loop_->BelongsToCurrentThread()); 174 DCHECK(task_runner_->BelongsToCurrentThread());
175 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 175 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
176 DCHECK(!init_cb_.is_null()); 176 DCHECK(!init_cb_.is_null());
177 DCHECK(read_cb_.is_null()); 177 DCHECK(read_cb_.is_null());
178 DCHECK(reset_cb_.is_null()); 178 DCHECK(reset_cb_.is_null());
179 179
180 decoder_selector_.reset(); 180 decoder_selector_.reset();
181 181
182 if (!selected_decoder) { 182 if (!selected_decoder) {
183 state_ = STATE_UNINITIALIZED; 183 state_ = STATE_UNINITIALIZED;
184 base::ResetAndReturn(&init_cb_).Run(false, false); 184 base::ResetAndReturn(&init_cb_).Run(false, false);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 298
299 state_ = STATE_PENDING_DEMUXER_READ; 299 state_ = STATE_PENDING_DEMUXER_READ;
300 stream_->Read( 300 stream_->Read(
301 base::Bind(&VideoFrameStream::OnBufferReady, weak_factory_.GetWeakPtr())); 301 base::Bind(&VideoFrameStream::OnBufferReady, weak_factory_.GetWeakPtr()));
302 } 302 }
303 303
304 void VideoFrameStream::OnBufferReady( 304 void VideoFrameStream::OnBufferReady(
305 DemuxerStream::Status status, 305 DemuxerStream::Status status,
306 const scoped_refptr<DecoderBuffer>& buffer) { 306 const scoped_refptr<DecoderBuffer>& buffer) {
307 DVLOG(2) << __FUNCTION__; 307 DVLOG(2) << __FUNCTION__;
308 DCHECK(message_loop_->BelongsToCurrentThread()); 308 DCHECK(task_runner_->BelongsToCurrentThread());
309 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_; 309 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_;
310 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 310 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
311 DCHECK(!read_cb_.is_null()); 311 DCHECK(!read_cb_.is_null());
312 DCHECK(stop_cb_.is_null()); 312 DCHECK(stop_cb_.is_null());
313 313
314 state_ = STATE_NORMAL; 314 state_ = STATE_NORMAL;
315 315
316 if (status == DemuxerStream::kConfigChanged) { 316 if (status == DemuxerStream::kConfigChanged) {
317 state_ = STATE_FLUSHING_DECODER; 317 state_ = STATE_FLUSHING_DECODER;
318 if (!reset_cb_.is_null()) { 318 if (!reset_cb_.is_null()) {
(...skipping 22 matching lines...) Expand all
341 SatisfyRead(DEMUXER_READ_ABORTED, NULL); 341 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
342 return; 342 return;
343 } 343 }
344 344
345 DCHECK(status == DemuxerStream::kOk) << status; 345 DCHECK(status == DemuxerStream::kOk) << status;
346 Decode(buffer); 346 Decode(buffer);
347 } 347 }
348 348
349 void VideoFrameStream::ReinitializeDecoder() { 349 void VideoFrameStream::ReinitializeDecoder() {
350 DVLOG(2) << __FUNCTION__; 350 DVLOG(2) << __FUNCTION__;
351 DCHECK(message_loop_->BelongsToCurrentThread()); 351 DCHECK(task_runner_->BelongsToCurrentThread());
352 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; 352 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
353 353
354 DCHECK(stream_->video_decoder_config().IsValidConfig()); 354 DCHECK(stream_->video_decoder_config().IsValidConfig());
355 state_ = STATE_REINITIALIZING_DECODER; 355 state_ = STATE_REINITIALIZING_DECODER;
356 decoder_->Initialize(stream_->video_decoder_config(), 356 decoder_->Initialize(stream_->video_decoder_config(),
357 base::Bind(&VideoFrameStream::OnDecoderReinitialized, 357 base::Bind(&VideoFrameStream::OnDecoderReinitialized,
358 weak_factory_.GetWeakPtr())); 358 weak_factory_.GetWeakPtr()));
359 } 359 }
360 360
361 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) { 361 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) {
362 DVLOG(2) << __FUNCTION__; 362 DVLOG(2) << __FUNCTION__;
363 DCHECK(message_loop_->BelongsToCurrentThread()); 363 DCHECK(task_runner_->BelongsToCurrentThread());
364 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; 364 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
365 DCHECK(stop_cb_.is_null()); 365 DCHECK(stop_cb_.is_null());
366 366
367 // ReinitializeDecoder() can be called in two cases: 367 // ReinitializeDecoder() can be called in two cases:
368 // 1, Flushing decoder finished (see OnFrameReady()). 368 // 1, Flushing decoder finished (see OnFrameReady()).
369 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). 369 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
370 // Also, Reset() can be called during pending ReinitializeDecoder(). 370 // Also, Reset() can be called during pending ReinitializeDecoder().
371 // This function needs to handle them all! 371 // This function needs to handle them all!
372 372
373 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; 373 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
(...skipping 10 matching lines...) Expand all
384 if (state_ == STATE_ERROR) { 384 if (state_ == STATE_ERROR) {
385 SatisfyRead(DECODE_ERROR, NULL); 385 SatisfyRead(DECODE_ERROR, NULL);
386 return; 386 return;
387 } 387 }
388 388
389 ReadFromDemuxerStream(); 389 ReadFromDemuxerStream();
390 } 390 }
391 391
392 void VideoFrameStream::ResetDecoder() { 392 void VideoFrameStream::ResetDecoder() {
393 DVLOG(2) << __FUNCTION__; 393 DVLOG(2) << __FUNCTION__;
394 DCHECK(message_loop_->BelongsToCurrentThread()); 394 DCHECK(task_runner_->BelongsToCurrentThread());
395 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 395 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
396 state_ == STATE_ERROR) << state_; 396 state_ == STATE_ERROR) << state_;
397 DCHECK(!reset_cb_.is_null()); 397 DCHECK(!reset_cb_.is_null());
398 398
399 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, 399 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset,
400 weak_factory_.GetWeakPtr())); 400 weak_factory_.GetWeakPtr()));
401 } 401 }
402 402
403 void VideoFrameStream::OnDecoderReset() { 403 void VideoFrameStream::OnDecoderReset() {
404 DVLOG(2) << __FUNCTION__; 404 DVLOG(2) << __FUNCTION__;
405 DCHECK(message_loop_->BelongsToCurrentThread()); 405 DCHECK(task_runner_->BelongsToCurrentThread());
406 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 406 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
407 state_ == STATE_ERROR) << state_; 407 state_ == STATE_ERROR) << state_;
408 // If Reset() was called during pending read, read callback should be fired 408 // If Reset() was called during pending read, read callback should be fired
409 // before the reset callback is fired. 409 // before the reset callback is fired.
410 DCHECK(read_cb_.is_null()); 410 DCHECK(read_cb_.is_null());
411 DCHECK(!reset_cb_.is_null()); 411 DCHECK(!reset_cb_.is_null());
412 DCHECK(stop_cb_.is_null()); 412 DCHECK(stop_cb_.is_null());
413 413
414 if (state_ != STATE_FLUSHING_DECODER) { 414 if (state_ != STATE_FLUSHING_DECODER) {
415 base::ResetAndReturn(&reset_cb_).Run(); 415 base::ResetAndReturn(&reset_cb_).Run();
416 return; 416 return;
417 } 417 }
418 418
419 // The resetting process will be continued in OnDecoderReinitialized(). 419 // The resetting process will be continued in OnDecoderReinitialized().
420 ReinitializeDecoder(); 420 ReinitializeDecoder();
421 } 421 }
422 422
423 void VideoFrameStream::StopDecoder() { 423 void VideoFrameStream::StopDecoder() {
424 DVLOG(2) << __FUNCTION__; 424 DVLOG(2) << __FUNCTION__;
425 DCHECK(message_loop_->BelongsToCurrentThread()); 425 DCHECK(task_runner_->BelongsToCurrentThread());
426 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 426 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
427 DCHECK(!stop_cb_.is_null()); 427 DCHECK(!stop_cb_.is_null());
428 428
429 decoder_->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped, 429 decoder_->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped,
430 weak_factory_.GetWeakPtr())); 430 weak_factory_.GetWeakPtr()));
431 } 431 }
432 432
433 void VideoFrameStream::OnDecoderStopped() { 433 void VideoFrameStream::OnDecoderStopped() {
434 DVLOG(2) << __FUNCTION__; 434 DVLOG(2) << __FUNCTION__;
435 DCHECK(message_loop_->BelongsToCurrentThread()); 435 DCHECK(task_runner_->BelongsToCurrentThread());
436 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 436 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
437 // If Stop() was called during pending read/reset, read/reset callback should 437 // If Stop() was called during pending read/reset, read/reset callback should
438 // be fired before the stop callback is fired. 438 // be fired before the stop callback is fired.
439 DCHECK(read_cb_.is_null()); 439 DCHECK(read_cb_.is_null());
440 DCHECK(reset_cb_.is_null()); 440 DCHECK(reset_cb_.is_null());
441 DCHECK(!stop_cb_.is_null()); 441 DCHECK(!stop_cb_.is_null());
442 442
443 state_ = STATE_STOPPED; 443 state_ = STATE_STOPPED;
444 stream_ = NULL; 444 stream_ = NULL;
445 decoder_.reset(); 445 decoder_.reset();
446 decrypting_demuxer_stream_.reset(); 446 decrypting_demuxer_stream_.reset();
447 base::ResetAndReturn(&stop_cb_).Run(); 447 base::ResetAndReturn(&stop_cb_).Run();
448 } 448 }
449 449
450 } // namespace media 450 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698