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

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

Issue 16274005: Separate DemuxerStream and VideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win64 Created 7 years, 5 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
« no previous file with comments | « media/filters/video_frame_stream.h ('k') | media/filters/video_frame_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 DCHECK(init_cb_.is_null()); 42 DCHECK(init_cb_.is_null());
43 DCHECK(!init_cb.is_null()); 43 DCHECK(!init_cb.is_null());
44 44
45 weak_this_ = weak_factory_.GetWeakPtr(); 45 weak_this_ = weak_factory_.GetWeakPtr();
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 decoder_selector_->SelectVideoDecoder(this, statistics_cb, base::Bind( 52 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder.
53 decoder_selector_->SelectVideoDecoder(stream, statistics_cb, base::Bind(
53 &VideoFrameStream::OnDecoderSelected, weak_this_)); 54 &VideoFrameStream::OnDecoderSelected, weak_this_));
54 } 55 }
55 56
56 void VideoFrameStream::ReadFrame(const VideoDecoder::ReadCB& read_cb) { 57 void VideoFrameStream::ReadFrame(const VideoDecoder::ReadCB& read_cb) {
57 DCHECK(message_loop_->BelongsToCurrentThread()); 58 DCHECK(message_loop_->BelongsToCurrentThread());
58 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 59 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
59 state_ == STATE_ERROR) << state_; 60 state_ == STATE_ERROR) << state_;
60 // No two reads in the flight at any time. 61 // No two reads in the flight at any time.
61 DCHECK(read_cb_.is_null()); 62 DCHECK(read_cb_.is_null());
62 // No read during resetting or stopping process. 63 // No read during resetting or stopping process.
63 DCHECK(reset_cb_.is_null()); 64 DCHECK(reset_cb_.is_null());
64 DCHECK(stop_cb_.is_null()); 65 DCHECK(stop_cb_.is_null());
65 66
67 read_cb_ = read_cb;
68
66 if (state_ == STATE_ERROR) { 69 if (state_ == STATE_ERROR) {
67 message_loop_->PostTask(FROM_HERE, base::Bind( 70 message_loop_->PostTask(FROM_HERE, base::Bind(
68 read_cb, VideoDecoder::kDecodeError, scoped_refptr<VideoFrame>())); 71 read_cb, VideoDecoder::kDecodeError, scoped_refptr<VideoFrame>()));
69 return; 72 return;
70 } 73 }
71 74
72 read_cb_ = read_cb; 75 if (state_ == STATE_FLUSHING_DECODER) {
73 decoder_->Read(base::Bind(&VideoFrameStream::OnFrameReady, weak_this_)); 76 FlushDecoder();
77 return;
78 }
79
80 ReadFromDemuxerStream();
74 } 81 }
75 82
76 // VideoDecoder API guarantees that if VideoDecoder::Reset() is called during
77 // a pending read, the read callback must be fired before the reset callback is
78 // fired. Therefore, we can call VideoDecoder::Reset() regardless of if we have
79 // a pending read and always satisfy the reset callback when the decoder reset
80 // is finished. The only exception is when Reset() is called during decoder
81 // reinitialization. In this case we cannot and don't need to reset the decoder.
82 // We should just wait for the reinitialization to finish to satisfy the reset
83 // callback.
84 void VideoFrameStream::Reset(const base::Closure& closure) { 83 void VideoFrameStream::Reset(const base::Closure& closure) {
85 DCHECK(message_loop_->BelongsToCurrentThread()); 84 DCHECK(message_loop_->BelongsToCurrentThread());
86 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 85 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
87 DCHECK(reset_cb_.is_null()); 86 DCHECK(reset_cb_.is_null());
88 DCHECK(stop_cb_.is_null()); 87 DCHECK(stop_cb_.is_null());
89 88
90 reset_cb_ = closure; 89 reset_cb_ = closure;
91 90
92 // VideoDecoder does not need to be and cannot be Reset() during 91 // During decoder reinitialization, VideoDecoder does not need to be and
93 // reinitialization. |decrypting_demuxer_stream_| was reset before decoder 92 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
94 // reinitialization. 93 // reinitialization.
95 if (state_ == STATE_REINITIALIZING_DECODER) 94 // During pending demuxer read, VideoDecoder will be reset after demuxer read
95 // is returned (in OnBufferReady()).
96 if (state_ == STATE_REINITIALIZING_DECODER ||
97 state_ == STATE_PENDING_DEMUXER_READ) {
96 return; 98 return;
99 }
97 100
98 // We may or may not have pending read, but we'll start to reset everything 101 // VideoDecoder API guarantees that if VideoDecoder::Reset() is called during
99 // regardless. 102 // a pending decode, the decode callback must be fired before the reset
103 // callback is fired. Therefore, we can call VideoDecoder::Reset() regardless
104 // of if we have a pending decode and always satisfy the reset callback when
105 // the decoder reset is finished.
100 if (decrypting_demuxer_stream_) { 106 if (decrypting_demuxer_stream_) {
101 decrypting_demuxer_stream_->Reset(base::Bind( 107 decrypting_demuxer_stream_->Reset(base::Bind(
102 &VideoFrameStream::ResetDecoder, weak_this_)); 108 &VideoFrameStream::ResetDecoder, weak_this_));
103 return; 109 return;
104 } 110 }
105 111
106 ResetDecoder(); 112 ResetDecoder();
107 } 113 }
108 114
109 void VideoFrameStream::Stop(const base::Closure& closure) { 115 void VideoFrameStream::Stop(const base::Closure& closure) {
110 DCHECK(message_loop_->BelongsToCurrentThread()); 116 DCHECK(message_loop_->BelongsToCurrentThread());
111 DCHECK_NE(state_, STATE_STOPPED) << state_; 117 DCHECK_NE(state_, STATE_STOPPED) << state_;
112 DCHECK(stop_cb_.is_null()); 118 DCHECK(stop_cb_.is_null());
113 119
114 stop_cb_ = closure; 120 stop_cb_ = closure;
115 121
116 // The stopping will continue after all of the following pending callbacks 122 // The stopping process will continue after the pending operation is finished.
117 // (if they are not null) are satisfied.
118 // TODO(xhwang): Now we cannot stop the initialization process through 123 // TODO(xhwang): Now we cannot stop the initialization process through
119 // VideoDecoderSelector. Fix this. See: http://crbug.com/222054 124 // VideoDecoderSelector. Fix this. See: http://crbug.com/222054
120 if (state_ == STATE_INITIALIZING) 125 if (state_ == STATE_INITIALIZING || state_ == STATE_PENDING_DEMUXER_READ)
121 return; 126 return;
122 127
123 // We may or may not have pending read and/or pending reset, but we'll start 128 // VideoDecoder API guarantees that if VideoDecoder::Stop() is called during
124 // to stop everything regardless. 129 // a pending reset or a pending decode, the callbacks are always fired in the
125 130 // decode -> reset -> stop order. Therefore, we can call VideoDecoder::Stop()
131 // regardless of if we have a pending decode or reset and always satisfy the
132 // stop callback when the decoder decode/reset is finished.
126 if (decrypting_demuxer_stream_) { 133 if (decrypting_demuxer_stream_) {
127 decrypting_demuxer_stream_->Reset(base::Bind( 134 decrypting_demuxer_stream_->Reset(base::Bind(
128 &VideoFrameStream::StopDecoder, weak_this_)); 135 &VideoFrameStream::StopDecoder, weak_this_));
129 return; 136 return;
130 } 137 }
131 138
139 // We may not have a |decoder_| if Stop() was called during initialization.
132 if (decoder_) { 140 if (decoder_) {
133 StopDecoder(); 141 StopDecoder();
134 return; 142 return;
135 } 143 }
136 144
137 state_ = STATE_STOPPED; 145 state_ = STATE_STOPPED;
138 stream_ = NULL; 146 stream_ = NULL;
139 decoder_.reset(); 147 decoder_.reset();
140 decrypting_demuxer_stream_.reset(); 148 decrypting_demuxer_stream_.reset();
141 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 149 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
142 } 150 }
143 151
144 bool VideoFrameStream::CanReadWithoutStalling() const { 152 bool VideoFrameStream::CanReadWithoutStalling() const {
145 DCHECK(message_loop_->BelongsToCurrentThread()); 153 DCHECK(message_loop_->BelongsToCurrentThread());
146 return decoder_->CanReadWithoutStalling(); 154 return decoder_->CanReadWithoutStalling();
147 } 155 }
148 156
149 void VideoFrameStream::Read(const DemuxerStream::ReadCB& demuxer_read_cb) {
150 DCHECK(message_loop_->BelongsToCurrentThread());
151
152 if (state_ == STATE_FLUSHING_DECODER) {
153 message_loop_->PostTask(FROM_HERE, base::Bind(
154 demuxer_read_cb, DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer()));
155 return;
156 }
157
158 stream_->Read(base::Bind(
159 &VideoFrameStream::OnBufferReady, weak_this_, demuxer_read_cb));
160 }
161
162 AudioDecoderConfig VideoFrameStream::audio_decoder_config() {
163 DCHECK(message_loop_->BelongsToCurrentThread());
164 LOG(FATAL) << "Method audio_decoder_config() called on VideoFrameStream";
165 return stream_->audio_decoder_config();
166 }
167
168 VideoDecoderConfig VideoFrameStream::video_decoder_config() {
169 DCHECK(message_loop_->BelongsToCurrentThread());
170 return stream_->video_decoder_config();
171 }
172
173 DemuxerStream::Type VideoFrameStream::type() {
174 DCHECK(message_loop_->BelongsToCurrentThread());
175 return VIDEO;
176 }
177
178 void VideoFrameStream::EnableBitstreamConverter() {
179 DCHECK(message_loop_->BelongsToCurrentThread());
180 NOTREACHED();
181 }
182
183 void VideoFrameStream::OnDecoderSelected( 157 void VideoFrameStream::OnDecoderSelected(
184 scoped_ptr<VideoDecoder> selected_decoder, 158 scoped_ptr<VideoDecoder> selected_decoder,
185 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 159 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
186 DCHECK(message_loop_->BelongsToCurrentThread()); 160 DCHECK(message_loop_->BelongsToCurrentThread());
187 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 161 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
188 DCHECK(!init_cb_.is_null()); 162 DCHECK(!init_cb_.is_null());
163 DCHECK(read_cb_.is_null());
164 DCHECK(reset_cb_.is_null());
165
189 decoder_selector_.reset(); 166 decoder_selector_.reset();
190 167
191 if (!selected_decoder) { 168 if (!selected_decoder) {
192 state_ = STATE_UNINITIALIZED; 169 state_ = STATE_UNINITIALIZED;
193 base::ResetAndReturn(&init_cb_).Run(false, false); 170 base::ResetAndReturn(&init_cb_).Run(false, false);
194 } else { 171 } else {
195 state_ = STATE_NORMAL; 172 state_ = STATE_NORMAL;
173 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass();
174 if (decrypting_demuxer_stream_)
175 stream_ = decrypting_demuxer_stream_.get();
196 decoder_ = selected_decoder.Pass(); 176 decoder_ = selected_decoder.Pass();
197 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); 177 if (decoder_->NeedsBitstreamConversion())
198 if (decoder_->NeedsBitstreamConversion()) {
199 stream_->EnableBitstreamConverter(); 178 stream_->EnableBitstreamConverter();
200 }
201 // TODO(xhwang): We assume |decoder_->HasAlpha()| does not change after 179 // TODO(xhwang): We assume |decoder_->HasAlpha()| does not change after
202 // reinitialization. Check this condition. 180 // reinitialization. Check this condition.
203 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha()); 181 base::ResetAndReturn(&init_cb_).Run(true, decoder_->HasAlpha());
204 } 182 }
205 183
206 // Stop() called during initialization. 184 // Stop() called during initialization.
207 if (!stop_cb_.is_null()) { 185 if (!stop_cb_.is_null()) {
208 Stop(base::ResetAndReturn(&stop_cb_)); 186 Stop(base::ResetAndReturn(&stop_cb_));
209 return; 187 return;
210 } 188 }
211 } 189 }
212 190
191 void VideoFrameStream::SatisfyRead(VideoDecoder::Status status,
192 const scoped_refptr<VideoFrame>& frame) {
193 DCHECK(!read_cb_.is_null());
194 base::ResetAndReturn(&read_cb_).Run(status, frame);
195 }
196
197 void VideoFrameStream::AbortRead() {
198 SatisfyRead(VideoDecoder::kOk, NULL);
199 }
200
201 void VideoFrameStream::Decode(const scoped_refptr<DecoderBuffer>& buffer) {
202 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
203 DCHECK(!read_cb_.is_null());
204 DCHECK(reset_cb_.is_null());
205 DCHECK(stop_cb_.is_null());
206 DCHECK(buffer);
207
208 decoder_->Decode(buffer, base::Bind(&VideoFrameStream::OnFrameReady,
209 weak_this_));
210 }
211
212 void VideoFrameStream::FlushDecoder() {
213 Decode(DecoderBuffer::CreateEOSBuffer());
214 }
215
213 void VideoFrameStream::OnFrameReady(const VideoDecoder::Status status, 216 void VideoFrameStream::OnFrameReady(const VideoDecoder::Status status,
214 const scoped_refptr<VideoFrame>& frame) { 217 const scoped_refptr<VideoFrame>& frame) {
215 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 218 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
216 DCHECK(!read_cb_.is_null()); 219 DCHECK(!read_cb_.is_null());
217 220
218 if (status != VideoDecoder::kOk) { 221 if (status == VideoDecoder::kDecodeError ||
222 status == VideoDecoder::kDecryptError) {
219 DCHECK(!frame.get()); 223 DCHECK(!frame.get());
220 state_ = STATE_ERROR; 224 state_ = STATE_ERROR;
221 base::ResetAndReturn(&read_cb_).Run(status, NULL); 225 SatisfyRead(status, NULL);
222 return; 226 return;
223 } 227 }
224 228
229 // Drop decoding result if Reset()/Stop() was called during decoding.
225 // The stopping/resetting process will be handled when the decoder is 230 // The stopping/resetting process will be handled when the decoder is
226 // stopped/reset. 231 // stopped/reset.
227 if (!stop_cb_.is_null() || !reset_cb_.is_null()) { 232 if (!stop_cb_.is_null() || !reset_cb_.is_null()) {
228 base::ResetAndReturn(&read_cb_).Run(VideoDecoder::kOk, NULL); 233 AbortRead();
229 return; 234 return;
230 } 235 }
231 236
232 // Decoder flush finished. Reinitialize the video decoder. 237 // Decoder flushed. Reinitialize the video decoder.
233 if (state_ == STATE_FLUSHING_DECODER && 238 if (state_ == STATE_FLUSHING_DECODER &&
234 status == VideoDecoder::kOk && frame->IsEndOfStream()) { 239 status == VideoDecoder::kOk && frame->IsEndOfStream()) {
235 ReinitializeDecoder(); 240 ReinitializeDecoder();
236 return; 241 return;
237 } 242 }
238 243
239 base::ResetAndReturn(&read_cb_).Run(status, frame); 244 if (status == VideoDecoder::kNotEnoughData) {
245 if (state_ == STATE_NORMAL)
246 ReadFromDemuxerStream();
247 else if (state_ == STATE_FLUSHING_DECODER)
248 FlushDecoder();
249 return;
250 }
251
252 SatisfyRead(status, frame);
253 }
254
255 void VideoFrameStream::ReadFromDemuxerStream() {
256 DCHECK_EQ(state_, STATE_NORMAL) << state_;
257 DCHECK(!read_cb_.is_null());
258 DCHECK(reset_cb_.is_null());
259 DCHECK(stop_cb_.is_null());
260
261 state_ = STATE_PENDING_DEMUXER_READ;
262 stream_->Read(base::Bind(&VideoFrameStream::OnBufferReady, weak_this_));
240 } 263 }
241 264
242 void VideoFrameStream::OnBufferReady( 265 void VideoFrameStream::OnBufferReady(
243 const DemuxerStream::ReadCB& demuxer_read_cb,
244 DemuxerStream::Status status, 266 DemuxerStream::Status status,
245 const scoped_refptr<DecoderBuffer>& buffer) { 267 const scoped_refptr<DecoderBuffer>& buffer) {
246 DCHECK(message_loop_->BelongsToCurrentThread()); 268 DCHECK(message_loop_->BelongsToCurrentThread());
247 // VideoFrameStream reads from demuxer stream only when in NORMAL state. 269 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_;
248 DCHECK_EQ(state_, STATE_NORMAL) << state_;
249 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 270 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
271 DCHECK(!read_cb_.is_null());
250 272
251 if (status == DemuxerStream::kConfigChanged) { 273 state_ = STATE_NORMAL;
252 DVLOG(2) << "OnBufferReady() - kConfigChanged"; 274
253 state_ = STATE_FLUSHING_DECODER; 275 // Reset()/Stop() was postponed during STATE_PENDING_DEMUXER_READ state.
254 demuxer_read_cb.Run(DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer()); 276 // We need to handle them in this function.
277
278 if (!stop_cb_.is_null()) {
279 AbortRead();
280 if (!reset_cb_.is_null())
281 Reset(base::ResetAndReturn(&reset_cb_));
282 Stop(base::ResetAndReturn(&stop_cb_));
255 return; 283 return;
256 } 284 }
257 285
258 DCHECK(status == DemuxerStream::kOk || status == DemuxerStream::kAborted); 286 if (status == DemuxerStream::kConfigChanged) {
259 demuxer_read_cb.Run(status, buffer); 287 state_ = STATE_FLUSHING_DECODER;
288 if (!reset_cb_.is_null()) {
289 AbortRead();
290 Reset(base::ResetAndReturn(&reset_cb_));
291 // Reinitialization will continue after Reset() is done.
292 } else {
293 FlushDecoder();
294 }
295 return;
296 }
297
298 if (!reset_cb_.is_null()) {
299 AbortRead();
300 Reset(base::ResetAndReturn(&reset_cb_));
301 return;
302 }
303
304 if (status == DemuxerStream::kAborted) {
305 AbortRead();
306 return;
307 }
308
309 DCHECK(status == DemuxerStream::kOk) << status;
310 Decode(buffer);
260 } 311 }
261 312
262 void VideoFrameStream::ReinitializeDecoder() { 313 void VideoFrameStream::ReinitializeDecoder() {
263 DCHECK(message_loop_->BelongsToCurrentThread()); 314 DCHECK(message_loop_->BelongsToCurrentThread());
264 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; 315 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
265 316
266 DemuxerStream* stream = this; 317 DCHECK(stream_->video_decoder_config().IsValidConfig());
267 if (decrypting_demuxer_stream_) {
268 // TODO(xhwang): Remove this hack! Since VideoFrameStream handles
269 // kConfigChange internally and hides it from downstream filters. The
270 // DecryptingDemuxerStream never receives kConfigChanged to reset it's
271 // internal VideoDecoderConfig. Call InitializeDecoderConfig() here
272 // explicitly to solve this. This will be removed when we separate the
273 // DemuxerStream from the VideoDecoder.
274 decrypting_demuxer_stream_->InitializeDecoderConfig();
275 stream = decrypting_demuxer_stream_.get();
276 }
277
278 DCHECK(stream->video_decoder_config().IsValidConfig());
279 state_ = STATE_REINITIALIZING_DECODER; 318 state_ = STATE_REINITIALIZING_DECODER;
280 decoder_->Initialize( 319 decoder_->Initialize(
281 stream, 320 stream_->video_decoder_config(),
282 base::Bind(&VideoFrameStream::OnDecoderReinitialized, weak_this_), 321 base::Bind(&VideoFrameStream::OnDecoderReinitialized, weak_this_),
283 statistics_cb_); 322 statistics_cb_);
284 } 323 }
285 324
286 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) { 325 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) {
287 DCHECK(message_loop_->BelongsToCurrentThread()); 326 DCHECK(message_loop_->BelongsToCurrentThread());
288 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; 327 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
289 328
329 // ReinitializeDecoder() can be called in two cases:
330 // 1, Flushing decoder finished (see OnFrameReady()).
331 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
332 // Also, Reset()/Stop() can be called during pending ReinitializeDecoder().
333 // This function needs to handle them all!
334
290 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; 335 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
291 336
292 if (!reset_cb_.is_null()) { 337 if (!read_cb_.is_null() && (!stop_cb_.is_null() || !reset_cb_.is_null()))
293 if (!read_cb_.is_null()) 338 AbortRead();
294 base::ResetAndReturn(&read_cb_).Run(VideoDecoder::kOk, NULL); 339
340 if (!reset_cb_.is_null())
295 base::ResetAndReturn(&reset_cb_).Run(); 341 base::ResetAndReturn(&reset_cb_).Run();
342
343 // If !stop_cb_.is_null(), it will be handled in OnDecoderStopped().
344
345 if (read_cb_.is_null())
296 return; 346 return;
297 }
298
299 DCHECK(!read_cb_.is_null());
300 347
301 if (!stop_cb_.is_null()) { 348 if (!stop_cb_.is_null()) {
302 base::ResetAndReturn(&read_cb_).Run(VideoDecoder::kOk, NULL); 349 base::ResetAndReturn(&read_cb_).Run(VideoDecoder::kOk, NULL);
303 return; 350 return;
304 } 351 }
305 352
306 if (state_ == STATE_ERROR) { 353 if (state_ == STATE_ERROR) {
307 base::ResetAndReturn(&read_cb_).Run(VideoDecoder::kDecodeError, NULL); 354 SatisfyRead(VideoDecoder::kDecodeError, NULL);
308 return; 355 return;
309 } 356 }
310 357
311 decoder_->Read(base::Bind(&VideoFrameStream::OnFrameReady, weak_this_)); 358 ReadFromDemuxerStream();
312 } 359 }
313 360
314 void VideoFrameStream::ResetDecoder() { 361 void VideoFrameStream::ResetDecoder() {
315 DCHECK(message_loop_->BelongsToCurrentThread()); 362 DCHECK(message_loop_->BelongsToCurrentThread());
316 DCHECK(state_ == STATE_NORMAL || 363 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
317 state_ == STATE_FLUSHING_DECODER ||
318 state_ == STATE_ERROR) << state_; 364 state_ == STATE_ERROR) << state_;
319 DCHECK(!reset_cb_.is_null()); 365 DCHECK(!reset_cb_.is_null());
320 366
321 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, weak_this_)); 367 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, weak_this_));
322 } 368 }
323 369
324 void VideoFrameStream::OnDecoderReset() { 370 void VideoFrameStream::OnDecoderReset() {
325 DCHECK(message_loop_->BelongsToCurrentThread()); 371 DCHECK(message_loop_->BelongsToCurrentThread());
326 DCHECK(state_ == STATE_NORMAL || 372 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
327 state_ == STATE_FLUSHING_DECODER ||
328 state_ == STATE_ERROR) << state_; 373 state_ == STATE_ERROR) << state_;
329 // If Reset() was called during pending read, read callback should be fired 374 // If Reset() was called during pending read, read callback should be fired
330 // before the reset callback is fired. 375 // before the reset callback is fired.
331 DCHECK(read_cb_.is_null()); 376 DCHECK(read_cb_.is_null());
332 DCHECK(!reset_cb_.is_null()); 377 DCHECK(!reset_cb_.is_null());
333 378
334 if (state_ != STATE_FLUSHING_DECODER || !stop_cb_.is_null()) { 379 if (state_ != STATE_FLUSHING_DECODER || !stop_cb_.is_null()) {
335 base::ResetAndReturn(&reset_cb_).Run(); 380 base::ResetAndReturn(&reset_cb_).Run();
336 return; 381 return;
337 } 382 }
(...skipping 20 matching lines...) Expand all
358 DCHECK(!stop_cb_.is_null()); 403 DCHECK(!stop_cb_.is_null());
359 404
360 state_ = STATE_STOPPED; 405 state_ = STATE_STOPPED;
361 stream_ = NULL; 406 stream_ = NULL;
362 decoder_.reset(); 407 decoder_.reset();
363 decrypting_demuxer_stream_.reset(); 408 decrypting_demuxer_stream_.reset();
364 base::ResetAndReturn(&stop_cb_).Run(); 409 base::ResetAndReturn(&stop_cb_).Run();
365 } 410 }
366 411
367 } // namespace media 412 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/video_frame_stream.h ('k') | media/filters/video_frame_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698