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

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

Issue 331863004: Revert 276344 "Add callback in VideoDecoder and AudioDecoder to ..." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/2049/src/
Patch Set: Created 6 years, 6 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/decoder_stream.h ('k') | media/filters/decoder_stream_traits.h » ('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 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 statistics_cb_ = statistics_cb; 73 statistics_cb_ = statistics_cb;
74 init_cb_ = init_cb; 74 init_cb_ = init_cb;
75 stream_ = stream; 75 stream_ = stream;
76 low_delay_ = low_delay; 76 low_delay_ = low_delay;
77 77
78 state_ = STATE_INITIALIZING; 78 state_ = STATE_INITIALIZING;
79 // TODO(xhwang): DecoderSelector only needs a config to select a decoder. 79 // TODO(xhwang): DecoderSelector only needs a config to select a decoder.
80 decoder_selector_->SelectDecoder( 80 decoder_selector_->SelectDecoder(
81 stream, low_delay, 81 stream, low_delay,
82 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 82 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
83 weak_factory_.GetWeakPtr()),
84 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
85 weak_factory_.GetWeakPtr())); 83 weak_factory_.GetWeakPtr()));
86 } 84 }
87 85
88 template <DemuxerStream::Type StreamType> 86 template <DemuxerStream::Type StreamType>
89 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { 87 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
90 FUNCTION_DVLOG(2); 88 FUNCTION_DVLOG(2);
91 DCHECK(task_runner_->BelongsToCurrentThread()); 89 DCHECK(task_runner_->BelongsToCurrentThread());
92 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 90 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
93 state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER || 91 state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER ||
94 state_ == STATE_PENDING_DEMUXER_READ) 92 state_ == STATE_PENDING_DEMUXER_READ)
(...skipping 13 matching lines...) Expand all
108 scoped_refptr<Output>())); 106 scoped_refptr<Output>()));
109 return; 107 return;
110 } 108 }
111 109
112 if (!ready_outputs_.empty()) { 110 if (!ready_outputs_.empty()) {
113 task_runner_->PostTask(FROM_HERE, base::Bind( 111 task_runner_->PostTask(FROM_HERE, base::Bind(
114 base::ResetAndReturn(&read_cb_), OK, ready_outputs_.front())); 112 base::ResetAndReturn(&read_cb_), OK, ready_outputs_.front()));
115 ready_outputs_.pop_front(); 113 ready_outputs_.pop_front();
116 } 114 }
117 115
118 if (state_ == STATE_NORMAL && CanDecodeMore()) 116 // Decoder may be in reinitializing state as result of the previous Read().
117 if (state_ == STATE_REINITIALIZING_DECODER)
118 return;
119
120 if (!CanDecodeMore())
121 return;
122
123 if (state_ == STATE_FLUSHING_DECODER) {
124 FlushDecoder();
125 return;
126 }
127
128 if (state_ != STATE_PENDING_DEMUXER_READ)
119 ReadFromDemuxerStream(); 129 ReadFromDemuxerStream();
120 } 130 }
121 131
122 template <DemuxerStream::Type StreamType> 132 template <DemuxerStream::Type StreamType>
123 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { 133 void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
124 FUNCTION_DVLOG(2); 134 FUNCTION_DVLOG(2);
125 DCHECK(task_runner_->BelongsToCurrentThread()); 135 DCHECK(task_runner_->BelongsToCurrentThread());
126 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 136 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
127 DCHECK(reset_cb_.is_null()); 137 DCHECK(reset_cb_.is_null());
128 DCHECK(stop_cb_.is_null()); 138 DCHECK(stop_cb_.is_null());
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 state_ = STATE_STOPPED; 209 state_ = STATE_STOPPED;
200 stream_ = NULL; 210 stream_ = NULL;
201 decoder_.reset(); 211 decoder_.reset();
202 decrypting_demuxer_stream_.reset(); 212 decrypting_demuxer_stream_.reset();
203 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 213 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
204 } 214 }
205 215
206 template <DemuxerStream::Type StreamType> 216 template <DemuxerStream::Type StreamType>
207 bool DecoderStream<StreamType>::CanReadWithoutStalling() const { 217 bool DecoderStream<StreamType>::CanReadWithoutStalling() const {
208 DCHECK(task_runner_->BelongsToCurrentThread()); 218 DCHECK(task_runner_->BelongsToCurrentThread());
209 return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling(); 219 return decoder_->CanReadWithoutStalling();
210 } 220 }
211 221
212 template <> 222 template <>
213 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const { 223 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const {
214 DCHECK(task_runner_->BelongsToCurrentThread()); 224 DCHECK(task_runner_->BelongsToCurrentThread());
215 return true; 225 return true;
216 } 226 }
217 227
218 template <DemuxerStream::Type StreamType> 228 template <DemuxerStream::Type StreamType>
219 int DecoderStream<StreamType>::GetMaxDecodeRequests() const {
220 return decoder_->GetMaxDecodeRequests();
221 }
222
223 template <>
224 int DecoderStream<DemuxerStream::AUDIO>::GetMaxDecodeRequests() const {
225 return 1;
226 }
227
228 template <DemuxerStream::Type StreamType>
229 bool DecoderStream<StreamType>::CanDecodeMore() const { 229 bool DecoderStream<StreamType>::CanDecodeMore() const {
230 DCHECK(task_runner_->BelongsToCurrentThread()); 230 DCHECK(task_runner_->BelongsToCurrentThread());
231 231
232 // Limit total number of outputs stored in |ready_outputs_| and being decoded. 232 // Limit total number of outputs stored in |ready_outputs_| and being decoded.
233 // It only makes sense to saturate decoder completely when output queue is 233 // It only makes sense to saturate decoder completely when output queue is
234 // empty. 234 // empty.
235 int num_decodes = 235 int num_decodes =
236 static_cast<int>(ready_outputs_.size()) + pending_decode_requests_; 236 static_cast<int>(ready_outputs_.size()) + pending_decode_requests_;
237 return num_decodes < GetMaxDecodeRequests(); 237 return num_decodes < decoder_->GetMaxDecodeRequests();
238 }
239
240 template <>
241 bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const {
242 DCHECK(task_runner_->BelongsToCurrentThread());
243 return !pending_decode_requests_ && ready_outputs_.empty();
238 } 244 }
239 245
240 template <DemuxerStream::Type StreamType> 246 template <DemuxerStream::Type StreamType>
241 void DecoderStream<StreamType>::OnDecoderSelected( 247 void DecoderStream<StreamType>::OnDecoderSelected(
242 scoped_ptr<Decoder> selected_decoder, 248 scoped_ptr<Decoder> selected_decoder,
243 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 249 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
244 FUNCTION_DVLOG(2); 250 FUNCTION_DVLOG(2);
245 DCHECK(task_runner_->BelongsToCurrentThread()); 251 DCHECK(task_runner_->BelongsToCurrentThread());
246 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 252 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
247 DCHECK(!init_cb_.is_null()); 253 DCHECK(!init_cb_.is_null());
(...skipping 29 matching lines...) Expand all
277 const scoped_refptr<Output>& output) { 283 const scoped_refptr<Output>& output) {
278 DCHECK(!read_cb_.is_null()); 284 DCHECK(!read_cb_.is_null());
279 base::ResetAndReturn(&read_cb_).Run(status, output); 285 base::ResetAndReturn(&read_cb_).Run(status, output);
280 } 286 }
281 287
282 template <DemuxerStream::Type StreamType> 288 template <DemuxerStream::Type StreamType>
283 void DecoderStream<StreamType>::Decode( 289 void DecoderStream<StreamType>::Decode(
284 const scoped_refptr<DecoderBuffer>& buffer) { 290 const scoped_refptr<DecoderBuffer>& buffer) {
285 FUNCTION_DVLOG(2); 291 FUNCTION_DVLOG(2);
286 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 292 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
287 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); 293 DCHECK(CanDecodeMore());
288 DCHECK(reset_cb_.is_null()); 294 DCHECK(reset_cb_.is_null());
289 DCHECK(stop_cb_.is_null()); 295 DCHECK(stop_cb_.is_null());
290 DCHECK(buffer); 296 DCHECK(buffer);
291 297
292 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); 298 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
293 299
294 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); 300 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this);
295 ++pending_decode_requests_; 301 ++pending_decode_requests_;
296 decoder_->Decode(buffer, 302 decoder_->Decode(buffer,
297 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, 303 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
298 weak_factory_.GetWeakPtr(), 304 weak_factory_.GetWeakPtr(),
299 buffer_size, 305 buffer_size));
300 buffer->end_of_stream()));
301 } 306 }
302 307
303 template <DemuxerStream::Type StreamType> 308 template <DemuxerStream::Type StreamType>
304 void DecoderStream<StreamType>::FlushDecoder() { 309 void DecoderStream<StreamType>::FlushDecoder() {
305 Decode(DecoderBuffer::CreateEOSBuffer()); 310 if (pending_decode_requests_ == 0)
311 Decode(DecoderBuffer::CreateEOSBuffer());
306 } 312 }
307 313
308 template <DemuxerStream::Type StreamType> 314 template <DemuxerStream::Type StreamType>
309 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, 315 void DecoderStream<StreamType>::OnDecodeOutputReady(
310 bool end_of_stream, 316 int buffer_size,
311 typename Decoder::Status status) { 317 typename Decoder::Status status,
312 FUNCTION_DVLOG(2) << status; 318 const scoped_refptr<Output>& output) {
319 FUNCTION_DVLOG(2) << status << " " << output;
313 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 320 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
314 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) 321 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
315 << state_; 322 << state_;
316 DCHECK(stop_cb_.is_null()); 323 DCHECK(stop_cb_.is_null());
324 DCHECK_EQ(status == Decoder::kOk, output != NULL);
317 DCHECK_GT(pending_decode_requests_, 0); 325 DCHECK_GT(pending_decode_requests_, 0);
318 326
319 --pending_decode_requests_; 327 --pending_decode_requests_;
320 328
321 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); 329 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this);
322 330
323 if (state_ == STATE_ERROR) { 331 if (state_ == STATE_ERROR) {
324 DCHECK(read_cb_.is_null()); 332 DCHECK(read_cb_.is_null());
325 return; 333 return;
326 } 334 }
327 335
336 if (status == Decoder::kDecodeError) {
337 state_ = STATE_ERROR;
338 ready_outputs_.clear();
339 if (!read_cb_.is_null())
340 SatisfyRead(DECODE_ERROR, NULL);
341 return;
342 }
343
344 if (status == Decoder::kDecryptError) {
345 state_ = STATE_ERROR;
346 ready_outputs_.clear();
347 if (!read_cb_.is_null())
348 SatisfyRead(DECRYPT_ERROR, NULL);
349 return;
350 }
351
352 if (status == Decoder::kAborted) {
353 if (!read_cb_.is_null())
354 SatisfyRead(ABORTED, NULL);
355 return;
356 }
357
358 // Any successful decode counts!
359 if (buffer_size > 0) {
360 StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
361 }
362
328 // Drop decoding result if Reset() was called during decoding. 363 // Drop decoding result if Reset() was called during decoding.
329 // The resetting process will be handled when the decoder is reset. 364 // The resetting process will be handled when the decoder is reset.
330 if (!reset_cb_.is_null()) 365 if (!reset_cb_.is_null())
331 return; 366 return;
332 367
333 switch (status) { 368 // Decoder flushed. Reinitialize the decoder.
334 case Decoder::kDecodeError: 369 if (state_ == STATE_FLUSHING_DECODER &&
335 case Decoder::kDecryptError: 370 status == Decoder::kOk && output->end_of_stream()) {
336 state_ = STATE_ERROR; 371 ReinitializeDecoder();
337 ready_outputs_.clear();
338 if (!read_cb_.is_null())
339 SatisfyRead(DECODE_ERROR, NULL);
340 break;
341
342 case Decoder::kAborted:
343 // Decoder can return kAborted only when Reset is pending.
344 NOTREACHED();
345 break;
346
347 case Decoder::kOk:
348 // Any successful decode counts!
349 if (buffer_size > 0) {
350 StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
351 }
352
353 if (state_ == STATE_NORMAL) {
354 if (CanDecodeMore() && !end_of_stream)
355 ReadFromDemuxerStream();
356 } else if (state_ == STATE_FLUSHING_DECODER) {
357 if (!pending_decode_requests_)
358 ReinitializeDecoder();
359 }
360 break;
361 }
362 }
363
364 template <DemuxerStream::Type StreamType>
365 void DecoderStream<StreamType>::OnDecodeOutputReady(
366 const scoped_refptr<Output>& output) {
367 FUNCTION_DVLOG(2) << output;
368 DCHECK(output);
369 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
370 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
371 << state_;
372
373 if (state_ == STATE_ERROR) {
374 DCHECK(read_cb_.is_null());
375 return; 372 return;
376 } 373 }
377 374
378 // Drop decoding result if Reset() was called during decoding. 375 if (status == Decoder::kNotEnoughData) {
379 // The resetting process will be handled when the decoder is reset. 376 if (state_ == STATE_NORMAL)
380 if (!reset_cb_.is_null()) 377 ReadFromDemuxerStream();
381 return; 378 else if (state_ == STATE_FLUSHING_DECODER)
382 379 FlushDecoder();
383 if (state_ == STATE_FLUSHING_DECODER && output->end_of_stream()) {
384 // ReinitializeDecoder() will be called from OnDecodeDone().
385 return; 380 return;
386 } 381 }
387 382
383 DCHECK(output);
384
388 // Store decoded output. 385 // Store decoded output.
389 ready_outputs_.push_back(output); 386 ready_outputs_.push_back(output);
387 scoped_refptr<Output> extra_output;
388 while ((extra_output = decoder_->GetDecodeOutput()) != NULL) {
389 ready_outputs_.push_back(extra_output);
390 }
390 391
391 // Satisfy outstanding read request, if any. 392 // Satisfy outstanding read request, if any.
392 if (!read_cb_.is_null()) { 393 if (!read_cb_.is_null()) {
393 scoped_refptr<Output> read_result = ready_outputs_.front(); 394 scoped_refptr<Output> read_result = ready_outputs_.front();
394 ready_outputs_.pop_front(); 395 ready_outputs_.pop_front();
395 SatisfyRead(OK, output); 396 SatisfyRead(OK, output);
396 } 397 }
397 } 398 }
398 399
399 template <DemuxerStream::Type StreamType> 400 template <DemuxerStream::Type StreamType>
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 453
453 if (!reset_cb_.is_null()) { 454 if (!reset_cb_.is_null()) {
454 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() 455 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
455 // which will continue the resetting process in it's callback. 456 // which will continue the resetting process in it's callback.
456 if (!decrypting_demuxer_stream_) 457 if (!decrypting_demuxer_stream_)
457 Reset(base::ResetAndReturn(&reset_cb_)); 458 Reset(base::ResetAndReturn(&reset_cb_));
458 return; 459 return;
459 } 460 }
460 461
461 if (status == DemuxerStream::kAborted) { 462 if (status == DemuxerStream::kAborted) {
462 if (!read_cb_.is_null()) 463 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
463 SatisfyRead(DEMUXER_READ_ABORTED, NULL);
464 return; 464 return;
465 } 465 }
466 466
467 if (!splice_observer_cb_.is_null() && !buffer->end_of_stream()) { 467 if (!splice_observer_cb_.is_null() && !buffer->end_of_stream()) {
468 const bool has_splice_ts = buffer->splice_timestamp() != kNoTimestamp(); 468 const bool has_splice_ts = buffer->splice_timestamp() != kNoTimestamp();
469 if (active_splice_ || has_splice_ts) { 469 if (active_splice_ || has_splice_ts) {
470 splice_observer_cb_.Run(buffer->splice_timestamp()); 470 splice_observer_cb_.Run(buffer->splice_timestamp());
471 active_splice_ = has_splice_ts; 471 active_splice_ = has_splice_ts;
472 } 472 }
473 } 473 }
(...skipping 13 matching lines...) Expand all
487 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; 487 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
488 DCHECK_EQ(pending_decode_requests_, 0); 488 DCHECK_EQ(pending_decode_requests_, 0);
489 489
490 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig()); 490 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig());
491 state_ = STATE_REINITIALIZING_DECODER; 491 state_ = STATE_REINITIALIZING_DECODER;
492 DecoderStreamTraits<StreamType>::Initialize( 492 DecoderStreamTraits<StreamType>::Initialize(
493 decoder_.get(), 493 decoder_.get(),
494 StreamTraits::GetDecoderConfig(*stream_), 494 StreamTraits::GetDecoderConfig(*stream_),
495 low_delay_, 495 low_delay_,
496 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, 496 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
497 weak_factory_.GetWeakPtr()),
498 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
499 weak_factory_.GetWeakPtr())); 497 weak_factory_.GetWeakPtr()));
500 } 498 }
501 499
502 template <DemuxerStream::Type StreamType> 500 template <DemuxerStream::Type StreamType>
503 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { 501 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) {
504 FUNCTION_DVLOG(2); 502 FUNCTION_DVLOG(2);
505 DCHECK(task_runner_->BelongsToCurrentThread()); 503 DCHECK(task_runner_->BelongsToCurrentThread());
506 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; 504 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
507 DCHECK(stop_cb_.is_null()); 505 DCHECK(stop_cb_.is_null());
508 506
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 decrypting_demuxer_stream_.reset(); 575 decrypting_demuxer_stream_.reset();
578 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also 576 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also
579 // posted in Stop(). 577 // posted in Stop().
580 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 578 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
581 } 579 }
582 580
583 template class DecoderStream<DemuxerStream::VIDEO>; 581 template class DecoderStream<DemuxerStream::VIDEO>;
584 template class DecoderStream<DemuxerStream::AUDIO>; 582 template class DecoderStream<DemuxerStream::AUDIO>;
585 583
586 } // namespace media 584 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/decoder_stream_traits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698