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

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

Issue 239893002: Allow multiple concurrent Decode() requests in VideoDecoder interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/decoder_stream.h" 5 #include "media/filters/decoder_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/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 ScopedVector<Decoder> decoders, 44 ScopedVector<Decoder> decoders,
45 const SetDecryptorReadyCB& set_decryptor_ready_cb) 45 const SetDecryptorReadyCB& set_decryptor_ready_cb)
46 : task_runner_(task_runner), 46 : task_runner_(task_runner),
47 state_(STATE_UNINITIALIZED), 47 state_(STATE_UNINITIALIZED),
48 stream_(NULL), 48 stream_(NULL),
49 decoder_selector_( 49 decoder_selector_(
50 new DecoderSelector<StreamType>(task_runner, 50 new DecoderSelector<StreamType>(task_runner,
51 decoders.Pass(), 51 decoders.Pass(),
52 set_decryptor_ready_cb)), 52 set_decryptor_ready_cb)),
53 active_splice_(false), 53 active_splice_(false),
54 pending_decode_requests_(0),
54 weak_factory_(this) {} 55 weak_factory_(this) {}
55 56
56 template <DemuxerStream::Type StreamType> 57 template <DemuxerStream::Type StreamType>
57 DecoderStream<StreamType>::~DecoderStream() { 58 DecoderStream<StreamType>::~DecoderStream() {
58 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; 59 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_;
59 } 60 }
60 61
61 template <DemuxerStream::Type StreamType> 62 template <DemuxerStream::Type StreamType>
62 void DecoderStream<StreamType>::Initialize(DemuxerStream* stream, 63 void DecoderStream<StreamType>::Initialize(DemuxerStream* stream,
63 const StatisticsCB& statistics_cb, 64 const StatisticsCB& statistics_cb,
(...skipping 14 matching lines...) Expand all
78 stream, 79 stream,
79 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 80 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
80 weak_factory_.GetWeakPtr())); 81 weak_factory_.GetWeakPtr()));
81 } 82 }
82 83
83 template <DemuxerStream::Type StreamType> 84 template <DemuxerStream::Type StreamType>
84 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { 85 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
85 FUNCTION_DVLOG(2); 86 FUNCTION_DVLOG(2);
86 DCHECK(task_runner_->BelongsToCurrentThread()); 87 DCHECK(task_runner_->BelongsToCurrentThread());
87 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 88 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
88 state_ == STATE_ERROR) << state_; 89 state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER ||
90 state_ == STATE_PENDING_DEMUXER_READ)
91 << state_;
89 // No two reads in the flight at any time. 92 // No two reads in the flight at any time.
90 DCHECK(read_cb_.is_null()); 93 DCHECK(read_cb_.is_null());
91 // No read during resetting or stopping process. 94 // No read during resetting or stopping process.
92 DCHECK(reset_cb_.is_null()); 95 DCHECK(reset_cb_.is_null());
93 DCHECK(stop_cb_.is_null()); 96 DCHECK(stop_cb_.is_null());
94 97
98 read_cb_ = read_cb;
99
95 if (state_ == STATE_ERROR) { 100 if (state_ == STATE_ERROR) {
96 task_runner_->PostTask(FROM_HERE, base::Bind( 101 task_runner_->PostTask(FROM_HERE,
97 read_cb, DECODE_ERROR, scoped_refptr<Output>())); 102 base::Bind(base::ResetAndReturn(&read_cb_),
103 DECODE_ERROR,
104 scoped_refptr<Output>()));
98 return; 105 return;
99 } 106 }
100 107
101 read_cb_ = read_cb; 108 if (!ready_outputs_.empty()) {
109 task_runner_->PostTask(FROM_HERE, base::Bind(
110 base::ResetAndReturn(&read_cb_), OK, ready_outputs_.front()));
111 ready_outputs_.pop_front();
112 }
113
114 // Decoder may be in reinitializing state as result of the previous Read().
115 if (state_ == STATE_REINITIALIZING_DECODER)
116 return;
117
118 if (!CanDecodeMore())
119 return;
102 120
103 if (state_ == STATE_FLUSHING_DECODER) { 121 if (state_ == STATE_FLUSHING_DECODER) {
104 FlushDecoder(); 122 FlushDecoder();
105 return; 123 return;
106 } 124 }
107 125
108 scoped_refptr<Output> output = decoder_->GetDecodeOutput(); 126 if (state_ != STATE_PENDING_DEMUXER_READ)
109 127 ReadFromDemuxerStream();
110 // If the decoder has queued output ready to go we don't need a demuxer read.
111 if (output) {
112 task_runner_->PostTask(
113 FROM_HERE, base::Bind(base::ResetAndReturn(&read_cb_), OK, output));
114 return;
115 }
116
117 ReadFromDemuxerStream();
118 } 128 }
119 129
120 template <DemuxerStream::Type StreamType> 130 template <DemuxerStream::Type StreamType>
121 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { 131 void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
122 FUNCTION_DVLOG(2); 132 FUNCTION_DVLOG(2);
123 DCHECK(task_runner_->BelongsToCurrentThread()); 133 DCHECK(task_runner_->BelongsToCurrentThread());
124 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 134 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
125 DCHECK(reset_cb_.is_null()); 135 DCHECK(reset_cb_.is_null());
126 DCHECK(stop_cb_.is_null()); 136 DCHECK(stop_cb_.is_null());
127 137
128 reset_cb_ = closure; 138 reset_cb_ = closure;
129 139
140 if (!read_cb_.is_null()) {
141 task_runner_->PostTask(FROM_HERE, base::Bind(
142 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
143 }
144
145 ready_outputs_.clear();
146
130 // During decoder reinitialization, the Decoder does not need to be and 147 // During decoder reinitialization, the Decoder does not need to be and
131 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder 148 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
132 // reinitialization. 149 // reinitialization.
133 if (state_ == STATE_REINITIALIZING_DECODER) 150 if (state_ == STATE_REINITIALIZING_DECODER)
134 return; 151 return;
135 152
136 // During pending demuxer read and when not using DecryptingDemuxerStream, 153 // During pending demuxer read and when not using DecryptingDemuxerStream,
137 // the Decoder will be reset after demuxer read is returned 154 // the Decoder will be reset after demuxer read is returned
138 // (in OnBufferReady()). 155 // (in OnBufferReady()).
139 if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_) 156 if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_)
140 return; 157 return;
141 158
142 // The Decoder API guarantees that if Decoder::Reset() is called during
143 // a pending decode, the decode callback must be fired before the reset
144 // callback is fired. Therefore, we can call Decoder::Reset() regardless
145 // of if we have a pending decode and always satisfy the reset callback when
146 // the decoder reset is finished.
147 if (decrypting_demuxer_stream_) { 159 if (decrypting_demuxer_stream_) {
148 decrypting_demuxer_stream_->Reset(base::Bind( 160 decrypting_demuxer_stream_->Reset(base::Bind(
149 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr())); 161 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr()));
150 return; 162 return;
151 } 163 }
152 164
153 ResetDecoder(); 165 ResetDecoder();
154 } 166 }
155 167
156 template <DemuxerStream::Type StreamType> 168 template <DemuxerStream::Type StreamType>
157 void DecoderStream<StreamType>::Stop(const base::Closure& closure) { 169 void DecoderStream<StreamType>::Stop(const base::Closure& closure) {
158 FUNCTION_DVLOG(2); 170 FUNCTION_DVLOG(2);
159 DCHECK(task_runner_->BelongsToCurrentThread()); 171 DCHECK(task_runner_->BelongsToCurrentThread());
160 DCHECK_NE(state_, STATE_STOPPED) << state_; 172 DCHECK_NE(state_, STATE_STOPPED) << state_;
161 DCHECK(stop_cb_.is_null()); 173 DCHECK(stop_cb_.is_null());
162 174
163 stop_cb_ = closure; 175 stop_cb_ = closure;
164 176
165 if (state_ == STATE_INITIALIZING) { 177 if (state_ == STATE_INITIALIZING) {
166 decoder_selector_->Abort(); 178 decoder_selector_->Abort();
167 return; 179 return;
168 } 180 }
169 181
170 DCHECK(init_cb_.is_null()); 182 DCHECK(init_cb_.is_null());
171 183
172 // All pending callbacks will be dropped. 184 // All pending callbacks will be dropped.
173 weak_factory_.InvalidateWeakPtrs(); 185 weak_factory_.InvalidateWeakPtrs();
174 186
175 // Post callbacks to prevent reentrance into this object. 187 // Post callbacks to prevent reentrance into this object.
176 if (!read_cb_.is_null()) 188 if (!read_cb_.is_null()) {
177 task_runner_->PostTask(FROM_HERE, base::Bind( 189 task_runner_->PostTask(FROM_HERE, base::Bind(
178 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); 190 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
191 }
179 if (!reset_cb_.is_null()) 192 if (!reset_cb_.is_null())
180 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); 193 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
181 194
182 if (decrypting_demuxer_stream_) { 195 if (decrypting_demuxer_stream_) {
183 decrypting_demuxer_stream_->Stop(base::Bind( 196 decrypting_demuxer_stream_->Stop(base::Bind(
184 &DecoderStream<StreamType>::StopDecoder, weak_factory_.GetWeakPtr())); 197 &DecoderStream<StreamType>::StopDecoder, weak_factory_.GetWeakPtr()));
185 return; 198 return;
186 } 199 }
187 200
188 // We may not have a |decoder_| if Stop() was called during initialization. 201 // We may not have a |decoder_| if Stop() was called during initialization.
(...skipping 15 matching lines...) Expand all
204 return decoder_->CanReadWithoutStalling(); 217 return decoder_->CanReadWithoutStalling();
205 } 218 }
206 219
207 template <> 220 template <>
208 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const { 221 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const {
209 DCHECK(task_runner_->BelongsToCurrentThread()); 222 DCHECK(task_runner_->BelongsToCurrentThread());
210 return true; 223 return true;
211 } 224 }
212 225
213 template <DemuxerStream::Type StreamType> 226 template <DemuxerStream::Type StreamType>
227 bool DecoderStream<StreamType>::CanDecodeMore() const {
228 DCHECK(task_runner_->BelongsToCurrentThread());
229
230 // Limit total number of outputs stored in |ready_outputs_| and being decoded.
231 // It only makes sense to saturate decoder completely when output queue is
232 // empty.
233 int num_decodes =
234 static_cast<int>(ready_outputs_.size()) + pending_decode_requests_;
235 return num_decodes < decoder_->GetMaxDecodeRequests();
236 }
237
238 template <>
239 bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const {
240 DCHECK(task_runner_->BelongsToCurrentThread());
241 return !pending_decode_requests_ && ready_outputs_.empty();
242 }
243
244 template <DemuxerStream::Type StreamType>
214 void DecoderStream<StreamType>::OnDecoderSelected( 245 void DecoderStream<StreamType>::OnDecoderSelected(
215 scoped_ptr<Decoder> selected_decoder, 246 scoped_ptr<Decoder> selected_decoder,
216 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 247 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
217 FUNCTION_DVLOG(2); 248 FUNCTION_DVLOG(2);
218 DCHECK(task_runner_->BelongsToCurrentThread()); 249 DCHECK(task_runner_->BelongsToCurrentThread());
219 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 250 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
220 DCHECK(!init_cb_.is_null()); 251 DCHECK(!init_cb_.is_null());
221 DCHECK(read_cb_.is_null()); 252 DCHECK(read_cb_.is_null());
222 DCHECK(reset_cb_.is_null()); 253 DCHECK(reset_cb_.is_null());
223 254
(...skipping 22 matching lines...) Expand all
246 277
247 template <DemuxerStream::Type StreamType> 278 template <DemuxerStream::Type StreamType>
248 void DecoderStream<StreamType>::SatisfyRead( 279 void DecoderStream<StreamType>::SatisfyRead(
249 Status status, 280 Status status,
250 const scoped_refptr<Output>& output) { 281 const scoped_refptr<Output>& output) {
251 DCHECK(!read_cb_.is_null()); 282 DCHECK(!read_cb_.is_null());
252 base::ResetAndReturn(&read_cb_).Run(status, output); 283 base::ResetAndReturn(&read_cb_).Run(status, output);
253 } 284 }
254 285
255 template <DemuxerStream::Type StreamType> 286 template <DemuxerStream::Type StreamType>
256 void DecoderStream<StreamType>::AbortRead() {
257 // Abort read during pending reset. It is safe to fire the |read_cb_| directly
258 // instead of posting it because the renderer won't call into this class
259 // again when it's in kFlushing state.
260 // TODO(xhwang): Improve the resetting process to avoid this dependency on the
261 // caller.
262 DCHECK(!reset_cb_.is_null());
263 SatisfyRead(ABORTED, NULL);
264 }
265
266 template <DemuxerStream::Type StreamType>
267 void DecoderStream<StreamType>::Decode( 287 void DecoderStream<StreamType>::Decode(
268 const scoped_refptr<DecoderBuffer>& buffer) { 288 const scoped_refptr<DecoderBuffer>& buffer) {
269 FUNCTION_DVLOG(2); 289 FUNCTION_DVLOG(2);
270 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 290 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
271 DCHECK(!read_cb_.is_null()); 291 DCHECK(CanDecodeMore());
272 DCHECK(reset_cb_.is_null()); 292 DCHECK(reset_cb_.is_null());
273 DCHECK(stop_cb_.is_null()); 293 DCHECK(stop_cb_.is_null());
274 DCHECK(buffer); 294 DCHECK(buffer);
275 295
276 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); 296 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
277 297
278 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); 298 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this);
299 ++pending_decode_requests_;
279 decoder_->Decode(buffer, 300 decoder_->Decode(buffer,
280 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, 301 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
281 weak_factory_.GetWeakPtr(), 302 weak_factory_.GetWeakPtr(),
282 buffer_size)); 303 buffer_size));
283 } 304 }
284 305
285 template <DemuxerStream::Type StreamType> 306 template <DemuxerStream::Type StreamType>
286 void DecoderStream<StreamType>::FlushDecoder() { 307 void DecoderStream<StreamType>::FlushDecoder() {
287 Decode(DecoderBuffer::CreateEOSBuffer()); 308 if (pending_decode_requests_ == 0)
309 Decode(DecoderBuffer::CreateEOSBuffer());
288 } 310 }
289 311
290 template <DemuxerStream::Type StreamType> 312 template <DemuxerStream::Type StreamType>
291 void DecoderStream<StreamType>::OnDecodeOutputReady( 313 void DecoderStream<StreamType>::OnDecodeOutputReady(
292 int buffer_size, 314 int buffer_size,
293 typename Decoder::Status status, 315 typename Decoder::Status status,
294 const scoped_refptr<Output>& output) { 316 const scoped_refptr<Output>& output) {
295 FUNCTION_DVLOG(2); 317 FUNCTION_DVLOG(2) << status << " " << output;
296 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 318 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
297 DCHECK(!read_cb_.is_null()); 319 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
320 << state_;
298 DCHECK(stop_cb_.is_null()); 321 DCHECK(stop_cb_.is_null());
299 DCHECK_EQ(status == Decoder::kOk, output != NULL); 322 DCHECK_EQ(status == Decoder::kOk, output != NULL);
323 DCHECK_GT(pending_decode_requests_, 0);
324
325 --pending_decode_requests_;
300 326
301 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); 327 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this);
302 328
329 if (state_ == STATE_ERROR) {
330 DCHECK(read_cb_.is_null());
331 return;
332 }
333
303 if (status == Decoder::kDecodeError) { 334 if (status == Decoder::kDecodeError) {
304 state_ = STATE_ERROR; 335 state_ = STATE_ERROR;
305 SatisfyRead(DECODE_ERROR, NULL); 336 ready_outputs_.clear();
337 if (!read_cb_.is_null())
338 SatisfyRead(DECODE_ERROR, NULL);
306 return; 339 return;
307 } 340 }
308 341
309 if (status == Decoder::kDecryptError) { 342 if (status == Decoder::kDecryptError) {
310 state_ = STATE_ERROR; 343 state_ = STATE_ERROR;
311 SatisfyRead(DECRYPT_ERROR, NULL); 344 ready_outputs_.clear();
345 if (!read_cb_.is_null())
346 SatisfyRead(DECRYPT_ERROR, NULL);
312 return; 347 return;
313 } 348 }
314 349
315 if (status == Decoder::kAborted) { 350 if (status == Decoder::kAborted) {
316 SatisfyRead(ABORTED, NULL); 351 if (!read_cb_.is_null())
352 SatisfyRead(ABORTED, NULL);
317 return; 353 return;
318 } 354 }
319 355
320 // Any successful decode counts! 356 // Any successful decode counts!
321 if (buffer_size > 0) { 357 if (buffer_size > 0) {
322 StreamTraits::ReportStatistics(statistics_cb_, buffer_size); 358 StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
323 } 359 }
324 360
325 // Drop decoding result if Reset() was called during decoding. 361 // Drop decoding result if Reset() was called during decoding.
326 // The resetting process will be handled when the decoder is reset. 362 // The resetting process will be handled when the decoder is reset.
327 if (!reset_cb_.is_null()) { 363 if (!reset_cb_.is_null())
328 AbortRead();
329 return; 364 return;
330 }
331 365
332 // Decoder flushed. Reinitialize the decoder. 366 // Decoder flushed. Reinitialize the decoder.
333 if (state_ == STATE_FLUSHING_DECODER && 367 if (state_ == STATE_FLUSHING_DECODER &&
334 status == Decoder::kOk && output->end_of_stream()) { 368 status == Decoder::kOk && output->end_of_stream()) {
335 ReinitializeDecoder(); 369 ReinitializeDecoder();
336 return; 370 return;
337 } 371 }
338 372
339 if (status == Decoder::kNotEnoughData) { 373 if (status == Decoder::kNotEnoughData) {
340 if (state_ == STATE_NORMAL) 374 if (state_ == STATE_NORMAL)
341 ReadFromDemuxerStream(); 375 ReadFromDemuxerStream();
342 else if (state_ == STATE_FLUSHING_DECODER) 376 else if (state_ == STATE_FLUSHING_DECODER)
343 FlushDecoder(); 377 FlushDecoder();
344 return; 378 return;
345 } 379 }
346 380
347 DCHECK(output); 381 DCHECK(output);
348 SatisfyRead(OK, output); 382
383 // Store decoded output.
384 ready_outputs_.push_back(output);
385 scoped_refptr<Output> extra_output;
386 while ((extra_output = decoder_->GetDecodeOutput()) != NULL) {
387 ready_outputs_.push_back(extra_output);
388 }
389
390 // Satisfy outstanding read request, if any.
391 if (!read_cb_.is_null()) {
392 scoped_refptr<Output> read_result = ready_outputs_.front();
393 ready_outputs_.pop_front();
394 SatisfyRead(OK, output);
395 }
349 } 396 }
350 397
351 template <DemuxerStream::Type StreamType> 398 template <DemuxerStream::Type StreamType>
352 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 399 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
353 FUNCTION_DVLOG(2); 400 FUNCTION_DVLOG(2);
354 DCHECK_EQ(state_, STATE_NORMAL) << state_; 401 DCHECK_EQ(state_, STATE_NORMAL) << state_;
355 DCHECK(!read_cb_.is_null()); 402 DCHECK(CanDecodeMore());
356 DCHECK(reset_cb_.is_null()); 403 DCHECK(reset_cb_.is_null());
357 DCHECK(stop_cb_.is_null()); 404 DCHECK(stop_cb_.is_null());
358 405
359 state_ = STATE_PENDING_DEMUXER_READ; 406 state_ = STATE_PENDING_DEMUXER_READ;
360 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 407 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
361 weak_factory_.GetWeakPtr())); 408 weak_factory_.GetWeakPtr()));
362 } 409 }
363 410
364 template <DemuxerStream::Type StreamType> 411 template <DemuxerStream::Type StreamType>
365 void DecoderStream<StreamType>::OnBufferReady( 412 void DecoderStream<StreamType>::OnBufferReady(
366 DemuxerStream::Status status, 413 DemuxerStream::Status status,
367 const scoped_refptr<DecoderBuffer>& buffer) { 414 const scoped_refptr<DecoderBuffer>& buffer) {
368 FUNCTION_DVLOG(2) << ": " << status; 415 FUNCTION_DVLOG(2) << ": " << status;
369 DCHECK(task_runner_->BelongsToCurrentThread()); 416 DCHECK(task_runner_->BelongsToCurrentThread());
370 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_; 417 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
418 state_ == STATE_STOPPED)
419 << state_;
371 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 420 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
372 DCHECK(!read_cb_.is_null());
373 DCHECK(stop_cb_.is_null()); 421 DCHECK(stop_cb_.is_null());
374 422
423 // Decoding has been stopped (e.g due to an error).
424 if (state_ != STATE_PENDING_DEMUXER_READ) {
425 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED);
426 DCHECK(read_cb_.is_null());
427 return;
428 }
429
375 state_ = STATE_NORMAL; 430 state_ = STATE_NORMAL;
376 431
377 if (status == DemuxerStream::kConfigChanged) { 432 if (status == DemuxerStream::kConfigChanged) {
378 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; 433 FUNCTION_DVLOG(2) << ": " << "ConfigChanged";
379 DCHECK(stream_->SupportsConfigChanges()); 434 DCHECK(stream_->SupportsConfigChanges());
380 435
381 if (!config_change_observer_cb_.is_null()) 436 if (!config_change_observer_cb_.is_null())
382 config_change_observer_cb_.Run(); 437 config_change_observer_cb_.Run();
383 438
384 state_ = STATE_FLUSHING_DECODER; 439 state_ = STATE_FLUSHING_DECODER;
385 if (!reset_cb_.is_null()) { 440 if (!reset_cb_.is_null()) {
386 AbortRead();
387 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() 441 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
388 // which will continue the resetting process in it's callback. 442 // which will continue the resetting process in it's callback.
389 if (!decrypting_demuxer_stream_) 443 if (!decrypting_demuxer_stream_)
390 Reset(base::ResetAndReturn(&reset_cb_)); 444 Reset(base::ResetAndReturn(&reset_cb_));
391 // Reinitialization will continue after Reset() is done. 445 // Reinitialization will continue after Reset() is done.
392 } else { 446 } else {
393 FlushDecoder(); 447 FlushDecoder();
394 } 448 }
395 return; 449 return;
396 } 450 }
397 451
398 if (!reset_cb_.is_null()) { 452 if (!reset_cb_.is_null()) {
399 AbortRead();
400 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() 453 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
401 // which will continue the resetting process in it's callback. 454 // which will continue the resetting process in it's callback.
402 if (!decrypting_demuxer_stream_) 455 if (!decrypting_demuxer_stream_)
403 Reset(base::ResetAndReturn(&reset_cb_)); 456 Reset(base::ResetAndReturn(&reset_cb_));
404 return; 457 return;
405 } 458 }
406 459
407 if (status == DemuxerStream::kAborted) { 460 if (status == DemuxerStream::kAborted) {
408 SatisfyRead(DEMUXER_READ_ABORTED, NULL); 461 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
409 return; 462 return;
410 } 463 }
411 464
412 if (!splice_observer_cb_.is_null() && !buffer->end_of_stream()) { 465 if (!splice_observer_cb_.is_null() && !buffer->end_of_stream()) {
413 const bool has_splice_ts = buffer->splice_timestamp() != kNoTimestamp(); 466 const bool has_splice_ts = buffer->splice_timestamp() != kNoTimestamp();
414 if (active_splice_ || has_splice_ts) { 467 if (active_splice_ || has_splice_ts) {
415 splice_observer_cb_.Run(buffer->splice_timestamp()); 468 splice_observer_cb_.Run(buffer->splice_timestamp());
416 active_splice_ = has_splice_ts; 469 active_splice_ = has_splice_ts;
417 } 470 }
418 } 471 }
419 472
420 DCHECK(status == DemuxerStream::kOk) << status; 473 DCHECK(status == DemuxerStream::kOk) << status;
421 Decode(buffer); 474 Decode(buffer);
475
476 // Read more data if the decoder supports multiple parallel decoding requests.
477 if (CanDecodeMore() && !buffer->end_of_stream())
478 ReadFromDemuxerStream();
422 } 479 }
423 480
424 template <DemuxerStream::Type StreamType> 481 template <DemuxerStream::Type StreamType>
425 void DecoderStream<StreamType>::ReinitializeDecoder() { 482 void DecoderStream<StreamType>::ReinitializeDecoder() {
426 FUNCTION_DVLOG(2); 483 FUNCTION_DVLOG(2);
427 DCHECK(task_runner_->BelongsToCurrentThread()); 484 DCHECK(task_runner_->BelongsToCurrentThread());
428 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; 485 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
486 DCHECK_EQ(pending_decode_requests_, 0);
429 487
430 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig()); 488 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig());
431 state_ = STATE_REINITIALIZING_DECODER; 489 state_ = STATE_REINITIALIZING_DECODER;
432 decoder_->Initialize( 490 decoder_->Initialize(
433 StreamTraits::GetDecoderConfig(*stream_), 491 StreamTraits::GetDecoderConfig(*stream_),
434 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, 492 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
435 weak_factory_.GetWeakPtr())); 493 weak_factory_.GetWeakPtr()));
436 } 494 }
437 495
438 template <DemuxerStream::Type StreamType> 496 template <DemuxerStream::Type StreamType>
439 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { 497 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) {
440 FUNCTION_DVLOG(2); 498 FUNCTION_DVLOG(2);
441 DCHECK(task_runner_->BelongsToCurrentThread()); 499 DCHECK(task_runner_->BelongsToCurrentThread());
442 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; 500 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
443 DCHECK(stop_cb_.is_null()); 501 DCHECK(stop_cb_.is_null());
444 502
445 // ReinitializeDecoder() can be called in two cases: 503 // ReinitializeDecoder() can be called in two cases:
446 // 1, Flushing decoder finished (see OnDecodeOutputReady()). 504 // 1, Flushing decoder finished (see OnDecodeOutputReady()).
447 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). 505 // 2, Reset() was called during flushing decoder (see OnDecoderReset()).
448 // Also, Reset() can be called during pending ReinitializeDecoder(). 506 // Also, Reset() can be called during pending ReinitializeDecoder().
449 // This function needs to handle them all! 507 // This function needs to handle them all!
450 508
451 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; 509 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
452 510
453 if (!reset_cb_.is_null()) { 511 if (!reset_cb_.is_null()) {
454 if (!read_cb_.is_null())
455 AbortRead();
456 base::ResetAndReturn(&reset_cb_).Run(); 512 base::ResetAndReturn(&reset_cb_).Run();
513 return;
457 } 514 }
458 515
459 if (read_cb_.is_null()) 516 if (read_cb_.is_null())
460 return; 517 return;
461 518
462 if (state_ == STATE_ERROR) { 519 if (state_ == STATE_ERROR) {
463 SatisfyRead(DECODE_ERROR, NULL); 520 SatisfyRead(DECODE_ERROR, NULL);
464 return; 521 return;
465 } 522 }
466 523
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 decrypting_demuxer_stream_.reset(); 571 decrypting_demuxer_stream_.reset();
515 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also 572 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also
516 // posted in Stop(). 573 // posted in Stop().
517 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 574 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
518 } 575 }
519 576
520 template class DecoderStream<DemuxerStream::VIDEO>; 577 template class DecoderStream<DemuxerStream::VIDEO>;
521 template class DecoderStream<DemuxerStream::AUDIO>; 578 template class DecoderStream<DemuxerStream::AUDIO>;
522 579
523 } // namespace media 580 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698