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

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

Issue 141243003: Add AudioBufferStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@decoderstream_rebased
Patch Set: Created 6 years, 10 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
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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "media/base/audio_decoder.h"
13 #include "media/base/bind_to_current_loop.h" 14 #include "media/base/bind_to_current_loop.h"
14 #include "media/base/decoder_buffer.h" 15 #include "media/base/decoder_buffer.h"
15 #include "media/base/demuxer_stream.h" 16 #include "media/base/demuxer_stream.h"
16 #include "media/base/video_decoder.h" 17 #include "media/base/video_decoder.h"
17 #include "media/filters/decrypting_demuxer_stream.h" 18 #include "media/filters/decrypting_demuxer_stream.h"
18 19
19 namespace media { 20 namespace media {
20 21
21 // TODO(rileya) Devise a better way of specifying trace/UMA/etc strings for 22 // TODO(rileya) Devise a better way of specifying trace/UMA/etc strings for
22 // templated classes such as this. 23 // templated classes such as this.
23 template <DemuxerStream::Type StreamType> 24 template <DemuxerStream::Type StreamType>
24 static const char* GetTraceString(); 25 static const char* GetTraceString();
25 26
26 template <> 27 template <>
27 const char* GetTraceString<DemuxerStream::VIDEO>() { 28 const char* GetTraceString<DemuxerStream::VIDEO>() {
28 return "DecoderStream<VIDEO>::Decode"; 29 return "DecoderStream<VIDEO>::Decode";
29 } 30 }
30 31
32 template <>
33 const char* GetTraceString<DemuxerStream::AUDIO>() {
34 return "DecoderStream<AUDIO>::Decode";
35 }
36
31 template <DemuxerStream::Type StreamType> 37 template <DemuxerStream::Type StreamType>
32 DecoderStream<StreamType>::DecoderStream( 38 DecoderStream<StreamType>::DecoderStream(
33 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 39 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
34 ScopedVector<Decoder> decoders, 40 ScopedVector<Decoder> decoders,
35 const SetDecryptorReadyCB& set_decryptor_ready_cb) 41 const SetDecryptorReadyCB& set_decryptor_ready_cb)
36 : task_runner_(task_runner), 42 : task_runner_(task_runner),
37 weak_factory_(this), 43 weak_factory_(this),
38 state_(STATE_UNINITIALIZED), 44 state_(STATE_UNINITIALIZED),
39 stream_(NULL), 45 stream_(NULL),
40 decoder_selector_( 46 decoder_selector_(
(...skipping 17 matching lines...) Expand all
58 DCHECK(!init_cb.is_null()); 64 DCHECK(!init_cb.is_null());
59 65
60 statistics_cb_ = statistics_cb; 66 statistics_cb_ = statistics_cb;
61 init_cb_ = init_cb; 67 init_cb_ = init_cb;
62 stream_ = stream; 68 stream_ = stream;
63 69
64 state_ = STATE_INITIALIZING; 70 state_ = STATE_INITIALIZING;
65 // TODO(xhwang): DecoderSelector only needs a config to select a decoder. 71 // TODO(xhwang): DecoderSelector only needs a config to select a decoder.
66 decoder_selector_->SelectDecoder( 72 decoder_selector_->SelectDecoder(
67 stream, 73 stream,
68 StatisticsCB(),
69 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 74 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
70 weak_factory_.GetWeakPtr())); 75 weak_factory_.GetWeakPtr()));
71 } 76 }
72 77
73 template <DemuxerStream::Type StreamType> 78 template <DemuxerStream::Type StreamType>
74 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { 79 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
75 DVLOG(2) << __FUNCTION__; 80 DVLOG(2) << __FUNCTION__;
76 DCHECK(task_runner_->BelongsToCurrentThread()); 81 DCHECK(task_runner_->BelongsToCurrentThread());
77 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 82 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
78 state_ == STATE_ERROR) << state_; 83 state_ == STATE_ERROR) << state_;
79 // No two reads in the flight at any time. 84 // No two reads in the flight at any time.
80 DCHECK(read_cb_.is_null()); 85 DCHECK(read_cb_.is_null());
81 // No read during resetting or stopping process. 86 // No read during resetting or stopping process.
82 DCHECK(reset_cb_.is_null()); 87 DCHECK(reset_cb_.is_null());
83 DCHECK(stop_cb_.is_null()); 88 DCHECK(stop_cb_.is_null());
84 89
85 if (state_ == STATE_ERROR) { 90 if (state_ == STATE_ERROR) {
86 task_runner_->PostTask(FROM_HERE, base::Bind( 91 task_runner_->PostTask(FROM_HERE, base::Bind(
87 read_cb, DECODE_ERROR, scoped_refptr<Output>())); 92 read_cb, DECODE_ERROR, scoped_refptr<Output>()));
88 return; 93 return;
89 } 94 }
90 95
91 read_cb_ = read_cb; 96 read_cb_ = read_cb;
92 97
93 if (state_ == STATE_FLUSHING_DECODER) { 98 if (state_ == STATE_FLUSHING_DECODER) {
94 FlushDecoder(); 99 FlushDecoder();
95 return; 100 return;
96 } 101 }
97 102
98 ReadFromDemuxerStream(); 103 if (!SendQueuedOutput())
104 ReadFromDemuxerStream();
99 } 105 }
100 106
101 template <DemuxerStream::Type StreamType> 107 template <DemuxerStream::Type StreamType>
102 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { 108 void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
103 DVLOG(2) << __FUNCTION__; 109 DVLOG(2) << __FUNCTION__;
104 DCHECK(task_runner_->BelongsToCurrentThread()); 110 DCHECK(task_runner_->BelongsToCurrentThread());
105 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 111 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
106 DCHECK(reset_cb_.is_null()); 112 DCHECK(reset_cb_.is_null());
107 DCHECK(stop_cb_.is_null()); 113 DCHECK(stop_cb_.is_null());
108 114
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 decrypting_demuxer_stream_.reset(); 184 decrypting_demuxer_stream_.reset();
179 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 185 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
180 } 186 }
181 187
182 template <DemuxerStream::Type StreamType> 188 template <DemuxerStream::Type StreamType>
183 bool DecoderStream<StreamType>::CanReadWithoutStalling() const { 189 bool DecoderStream<StreamType>::CanReadWithoutStalling() const {
184 DCHECK(task_runner_->BelongsToCurrentThread()); 190 DCHECK(task_runner_->BelongsToCurrentThread());
185 return decoder_->CanReadWithoutStalling(); 191 return decoder_->CanReadWithoutStalling();
186 } 192 }
187 193
194 template <>
195 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const {
196 DCHECK(task_runner_->BelongsToCurrentThread());
197 return true;
198 }
199
188 template <DemuxerStream::Type StreamType> 200 template <DemuxerStream::Type StreamType>
189 void DecoderStream<StreamType>::OnDecoderSelected( 201 void DecoderStream<StreamType>::OnDecoderSelected(
190 scoped_ptr<Decoder> selected_decoder, 202 scoped_ptr<Decoder> selected_decoder,
191 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 203 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
192 DVLOG(2) << __FUNCTION__; 204 DVLOG(2) << __FUNCTION__;
193 DCHECK(task_runner_->BelongsToCurrentThread()); 205 DCHECK(task_runner_->BelongsToCurrentThread());
194 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 206 DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
195 DCHECK(!init_cb_.is_null()); 207 DCHECK(!init_cb_.is_null());
196 DCHECK(read_cb_.is_null()); 208 DCHECK(read_cb_.is_null());
197 DCHECK(reset_cb_.is_null()); 209 DCHECK(reset_cb_.is_null());
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 } 324 }
313 325
314 if (status == Decoder::kNotEnoughData) { 326 if (status == Decoder::kNotEnoughData) {
315 if (state_ == STATE_NORMAL) 327 if (state_ == STATE_NORMAL)
316 ReadFromDemuxerStream(); 328 ReadFromDemuxerStream();
317 else if (state_ == STATE_FLUSHING_DECODER) 329 else if (state_ == STATE_FLUSHING_DECODER)
318 FlushDecoder(); 330 FlushDecoder();
319 return; 331 return;
320 } 332 }
321 333
334 DCHECK(output);
322 SatisfyRead(OK, output); 335 SatisfyRead(OK, output);
323 } 336 }
324 337
325 template <DemuxerStream::Type StreamType> 338 template <DemuxerStream::Type StreamType>
326 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 339 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
327 DVLOG(2) << __FUNCTION__; 340 DVLOG(2) << __FUNCTION__;
328 DCHECK_EQ(state_, STATE_NORMAL) << state_; 341 DCHECK_EQ(state_, STATE_NORMAL) << state_;
329 DCHECK(!read_cb_.is_null()); 342 DCHECK(!read_cb_.is_null());
330 DCHECK(reset_cb_.is_null()); 343 DCHECK(reset_cb_.is_null());
331 DCHECK(stop_cb_.is_null()); 344 DCHECK(stop_cb_.is_null());
332 345
333 state_ = STATE_PENDING_DEMUXER_READ; 346 state_ = STATE_PENDING_DEMUXER_READ;
334 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 347 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
335 weak_factory_.GetWeakPtr())); 348 weak_factory_.GetWeakPtr()));
336 } 349 }
337 350
338 template <DemuxerStream::Type StreamType> 351 template <DemuxerStream::Type StreamType>
352 bool DecoderStream<StreamType>::SendQueuedOutput() {
353 return false;
354 }
355
356 template <>
357 bool DecoderStream<DemuxerStream::AUDIO>::SendQueuedOutput() {
xhwang 2014/02/27 19:52:28 The name "SendQueuedOutput" is a bit odd. How abou
358 AudioDecoder::Status status;
359 if (scoped_refptr<AudioBuffer> buffer = decoder_->GetAudioBuffer(&status)) {
360 OnDecodeOutputReady(0, status, buffer);
xhwang 2014/02/27 19:52:28 since the first parameter is always 0, how about c
361 return true;
362 }
363 return false;
364 }
365
366 template <DemuxerStream::Type StreamType>
339 void DecoderStream<StreamType>::OnBufferReady( 367 void DecoderStream<StreamType>::OnBufferReady(
340 DemuxerStream::Status status, 368 DemuxerStream::Status status,
341 const scoped_refptr<DecoderBuffer>& buffer) { 369 const scoped_refptr<DecoderBuffer>& buffer) {
342 DVLOG(2) << __FUNCTION__; 370 DVLOG(2) << __FUNCTION__;
343 DCHECK(task_runner_->BelongsToCurrentThread()); 371 DCHECK(task_runner_->BelongsToCurrentThread());
344 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_; 372 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_;
345 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 373 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
346 DCHECK(!read_cb_.is_null()); 374 DCHECK(!read_cb_.is_null());
347 DCHECK(stop_cb_.is_null()); 375 DCHECK(stop_cb_.is_null());
348 376
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 DCHECK(status == DemuxerStream::kOk) << status; 408 DCHECK(status == DemuxerStream::kOk) << status;
381 Decode(buffer); 409 Decode(buffer);
382 } 410 }
383 411
384 template <DemuxerStream::Type StreamType> 412 template <DemuxerStream::Type StreamType>
385 void DecoderStream<StreamType>::ReinitializeDecoder() { 413 void DecoderStream<StreamType>::ReinitializeDecoder() {
386 DVLOG(2) << __FUNCTION__; 414 DVLOG(2) << __FUNCTION__;
387 DCHECK(task_runner_->BelongsToCurrentThread()); 415 DCHECK(task_runner_->BelongsToCurrentThread());
388 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; 416 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
389 417
390 // TODO(rileya): Specialize this for audio, or, better yet, change 418 DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig());
391 // DemuxerStream config getters to be templated.
392 DCHECK(stream_->video_decoder_config().IsValidConfig());
393 state_ = STATE_REINITIALIZING_DECODER; 419 state_ = STATE_REINITIALIZING_DECODER;
394 decoder_->Initialize( 420 decoder_->Initialize(
395 stream_->video_decoder_config(), 421 StreamTraits::GetDecoderConfig(*stream_),
396 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, 422 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
397 weak_factory_.GetWeakPtr())); 423 weak_factory_.GetWeakPtr()));
398 } 424 }
399 425
400 template <DemuxerStream::Type StreamType> 426 template <DemuxerStream::Type StreamType>
401 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { 427 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) {
402 DVLOG(2) << __FUNCTION__; 428 DVLOG(2) << __FUNCTION__;
403 DCHECK(task_runner_->BelongsToCurrentThread()); 429 DCHECK(task_runner_->BelongsToCurrentThread());
404 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; 430 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
405 DCHECK(stop_cb_.is_null()); 431 DCHECK(stop_cb_.is_null());
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 DCHECK(!stop_cb_.is_null()); 511 DCHECK(!stop_cb_.is_null());
486 512
487 state_ = STATE_STOPPED; 513 state_ = STATE_STOPPED;
488 stream_ = NULL; 514 stream_ = NULL;
489 decoder_.reset(); 515 decoder_.reset();
490 decrypting_demuxer_stream_.reset(); 516 decrypting_demuxer_stream_.reset();
491 base::ResetAndReturn(&stop_cb_).Run(); 517 base::ResetAndReturn(&stop_cb_).Run();
492 } 518 }
493 519
494 template class DecoderStream<DemuxerStream::VIDEO>; 520 template class DecoderStream<DemuxerStream::VIDEO>;
521 template class DecoderStream<DemuxerStream::AUDIO>;
495 } // namespace media 522 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698